From ae45c72960d0db19f60339876a771c5410507f13 Mon Sep 17 00:00:00 2001 From: David Rowley Date: Tue, 6 Jan 2026 17:31:20 +1300 Subject: [PATCH] Fix issue with EVENT TRIGGERS and ALTER PUBLICATION When processing the "publish" options of an ALTER PUBLICATION command, we call SplitIdentifierString() to split the options into a List of strings. Since SplitIdentifierString() modifies the delimiter character and puts NULs in their place, this would overwrite the memory of the AlterPublicationStmt. Later in AlterPublicationOptions(), the modified AlterPublicationStmt is copied for event triggers, which would result in the event trigger only seeing the first "publish" option rather than all options that were specified in the command. To fix this, make a copy of the string before passing to SplitIdentifierString(). Here we also adjust a similar case in the pgoutput plugin. There's no known issues caused by SplitIdentifierString() here, so this is being done out of paranoia. Thanks to Henson Choi for putting together an example case showing the ALTER PUBLICATION issue. Author: sunil s Reviewed-by: Henson Choi Reviewed-by: zengman Backpatch-through: 14 --- src/backend/commands/publicationcmds.c | 7 ++++++- src/backend/replication/pgoutput/pgoutput.c | 6 +++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/backend/commands/publicationcmds.c b/src/backend/commands/publicationcmds.c index e288dd41cdc..9347b99aa9b 100644 --- a/src/backend/commands/publicationcmds.c +++ b/src/backend/commands/publicationcmds.c @@ -96,7 +96,12 @@ parse_publication_options(List *options, pubactions->pubtruncate = false; *publish_given = true; - publish = defGetString(defel); + + /* + * SplitIdentifierString destructively modifies its input, so make + * a copy so we don't modify the memory of the executing statement + */ + publish = pstrdup(defGetString(defel)); if (!SplitIdentifierString(publish, ',', &publish_list)) ereport(ERROR, diff --git a/src/backend/replication/pgoutput/pgoutput.c b/src/backend/replication/pgoutput/pgoutput.c index a81215cff86..e7b85fcdddf 100644 --- a/src/backend/replication/pgoutput/pgoutput.c +++ b/src/backend/replication/pgoutput/pgoutput.c @@ -220,7 +220,11 @@ parse_output_parameters(List *options, PGOutputData *data) errmsg("conflicting or redundant options"))); publication_names_given = true; - if (!SplitIdentifierString(strVal(defel->arg), ',', + /* + * Pass a copy of the DefElem->arg since SplitIdentifierString + * modifies its input. + */ + if (!SplitIdentifierString(pstrdup(strVal(defel->arg)), ',', &data->publication_names)) ereport(ERROR, (errcode(ERRCODE_INVALID_NAME),