1
0
mirror of https://github.com/postgres/postgres.git synced 2026-10-23 13:29:09 +03:00

Tighten proto_version parsing in pgoutput

This is similar to 58ff4a0a08, but this time for the parameter
"proto_version", when given as a parameter to pgoutput for logical
replication.  strtoul() lacked a check for an empty string, leading to
an inconsistent behavior depending on the platform.

The author has originally proposed a TAP test to check this empty value
pattern.  I have added a cheaper SQL query, instead, test_decoding
including a test area where this is possible.

Author: Tristan Partin <tristan@partin.io>
Discussion: https://postgr.es/m/DKBS2Z9CGARC.2T07O6TJYSE8B@partin.io
This commit is contained in:
Michael Paquier
2026-08-06 16:46:03 +09:00
parent 58ff4a0a08
commit 290bb8afe6
3 changed files with 10 additions and 2 deletions

View File

@@ -292,6 +292,10 @@ SELECT pg_replication_origin_session_setup('regress_test_decoding: regression_sl
(1 row)
INSERT INTO target_tbl(data) VALUES ('test data');
-- invalid proto_version
SELECT pg_logical_slot_peek_binary_changes('regression_slot', NULL, NULL, 'proto_version', '', 'publication_names', 'pub', 'origin', 'none');
ERROR: invalid proto_version
CONTEXT: slot "regression_slot", output plugin "pgoutput", in the startup callback
-- The replayed change will be filtered.
SELECT count(*) = 0 FROM pg_logical_slot_peek_binary_changes('regression_slot', NULL, NULL, 'proto_version', '4', 'publication_names', 'pub', 'origin', 'none');
?column?

View File

@@ -138,6 +138,9 @@ SELECT pg_replication_origin_session_setup('regress_test_decoding: regression_sl
INSERT INTO target_tbl(data) VALUES ('test data');
-- invalid proto_version
SELECT pg_logical_slot_peek_binary_changes('regression_slot', NULL, NULL, 'proto_version', '', 'publication_names', 'pub', 'origin', 'none');
-- The replayed change will be filtered.
SELECT count(*) = 0 FROM pg_logical_slot_peek_binary_changes('regression_slot', NULL, NULL, 'proto_version', '4', 'publication_names', 'pub', 'origin', 'none');

View File

@@ -316,6 +316,7 @@ parse_output_parameters(List *options, PGOutputData *data)
{
unsigned long parsed;
char *endptr;
const char *val = strVal(defel->arg);
if (protocol_version_given)
ereport(ERROR,
@@ -324,8 +325,8 @@ parse_output_parameters(List *options, PGOutputData *data)
protocol_version_given = true;
errno = 0;
parsed = strtoul(strVal(defel->arg), &endptr, 10);
if (errno != 0 || *endptr != '\0')
parsed = strtoul(val, &endptr, 10);
if (endptr == val || errno != 0 || *endptr != '\0')
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("invalid proto_version")));