From b8b991398a4c6be2bee0ac56457bcedb5edb1d06 Mon Sep 17 00:00:00 2001 From: Ian Barwick Date: Thu, 16 Nov 2017 10:36:48 +0900 Subject: [PATCH] Escape double-quotes in strings passed to an event notification script The string in question will be generated internally by repmgr as a simple one-line string with no control characters etc., so all that needs to be escaped at the moment are any double quotes. --- Makefile.in | 2 +- dbutils.c | 10 ++++++++-- repmgrd-bdr.c | 4 ++-- strutil.c | 25 +++++++++++++++++++++++++ strutil.h | 2 ++ 5 files changed, 38 insertions(+), 5 deletions(-) diff --git a/Makefile.in b/Makefile.in index 55845ff4..97f2bcc9 100644 --- a/Makefile.in +++ b/Makefile.in @@ -40,7 +40,7 @@ REPMGR_CLIENT_OBJS = repmgr-client.o \ repmgr-action-primary.o repmgr-action-standby.o repmgr-action-witness.o \ repmgr-action-bdr.o repmgr-action-cluster.o repmgr-action-node.o \ configfile.o log.o strutil.o controldata.o dirutil.o compat.o dbutils.o -REPMGRD_OBJS = repmgrd.o repmgrd-physical.o repmgrd-bdr.o configfile.o log.o dbutils.o strutil.o controldata.o +REPMGRD_OBJS = repmgrd.o repmgrd-physical.o repmgrd-bdr.o configfile.o log.o dbutils.o strutil.o controldata.o compat.o DATE=$(shell date "+%Y-%m-%d") repmgr_version.h: repmgr_version.h.in diff --git a/dbutils.c b/dbutils.c index c92f0ce9..6632e4bd 100644 --- a/dbutils.c +++ b/dbutils.c @@ -27,7 +27,6 @@ #include "repmgr.h" #include "dbutils.h" #include "controldata.h" - #include "dirutil.h" /* mainly for use by repmgrd */ @@ -3086,6 +3085,7 @@ _create_event(PGconn *conn, t_configuration_options *options, int node_id, char char *end_ptr = NULL; int r = 0; + log_verbose(LOG_DEBUG, "_create_event(): command is '%s'", options->event_notification_command); /* * If configuration option 'event_notifications' was provided, check * if this event is one of the ones listed; if not listed, don't @@ -3164,8 +3164,14 @@ _create_event(PGconn *conn, t_configuration_options *options, int node_id, char src_ptr++; if (details != NULL) { - strlcpy(dst_ptr, details, end_ptr - dst_ptr); + PQExpBufferData details_escaped; + initPQExpBuffer(&details_escaped); + + escape_double_quotes(details, &details_escaped); + + strlcpy(dst_ptr, details_escaped.data, end_ptr - dst_ptr); dst_ptr += strlen(dst_ptr); + termPQExpBuffer(&details_escaped); } break; case 's': diff --git a/repmgrd-bdr.c b/repmgrd-bdr.c index b17c3943..25006fe2 100644 --- a/repmgrd-bdr.c +++ b/repmgrd-bdr.c @@ -472,8 +472,8 @@ do_bdr_failover(NodeInfoList *nodes, t_node_info *monitored_node) * event "bdr_failover" */ - create_event_notification_extended( - next_node_conn, + + create_event_notification_extended(next_node_conn, &config_file_options, monitored_node->node_id, "bdr_failover", diff --git a/strutil.c b/strutil.c index ed352758..dbd978a6 100644 --- a/strutil.c +++ b/strutil.c @@ -369,6 +369,31 @@ escape_string(PGconn *conn, const char *string) } +/* + * simple function to escape double quotes only + */ + +void +escape_double_quotes(char *string, PQExpBufferData *out) +{ + char *ptr; + + for (ptr = string; *ptr; ptr++) + { + if (*ptr == '"') + { + if ( (ptr == string) || (ptr > string && *(ptr - 1) != '\\')) + { + appendPQExpBufferChar(out, '\\'); + } + } + appendPQExpBufferChar(out, *ptr); + } + + return; +} + + char * string_skip_prefix(const char *prefix, char *string) { diff --git a/strutil.h b/strutil.h index bc1ce671..df7ea9f2 100644 --- a/strutil.h +++ b/strutil.h @@ -142,6 +142,8 @@ extern char *escape_recovery_conf_value(const char *src); extern char *escape_string(PGconn *conn, const char *string); +extern void escape_double_quotes(char *string, PQExpBufferData *out); + extern void append_where_clause(PQExpBufferData *where_clause, const char *clause,...) __attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3)));