From adc57cfa252f9e0cd567a9d9f93295323ea9fe3b Mon Sep 17 00:00:00 2001 From: Bo Peng Date: Thu, 1 May 2025 11:36:55 +0900 Subject: [PATCH] Fix json_writer did not properly encode special characters. Pgpool would crash when the watchdog was enabled if wd_authkey contained special characters (e.g., a backslash). The patch was originally created by Martijn van Duren and revised by Bo Peng. --- src/utils/json_writer.c | 44 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/src/utils/json_writer.c b/src/utils/json_writer.c index 1f7133843..7737390ce 100644 --- a/src/utils/json_writer.c +++ b/src/utils/json_writer.c @@ -26,6 +26,7 @@ #include "utils/palloc.h" #include "utils/json_writer.h" +static void jw_put_string_escape(JsonNode * jNode, char *string); static inline int jw_get_current_element_count(JsonNode * jNode); static inline void jw_inc_current_element_count(JsonNode * jNode); static inline JWElementType jw_get_current_element_type(JsonNode * jNode); @@ -67,11 +68,52 @@ jw_put_string(JsonNode * jNode, char *key, char *value) if (jw_get_current_element_count(jNode) > 0) appendStringInfoChar(jNode->buf, ','); - appendStringInfo(jNode->buf, "\"%s\":\"%s\"", key, value); + jw_put_string_escape(jNode, key); + appendStringInfoChar(jNode->buf, ':'); + jw_put_string_escape(jNode, value); jw_inc_current_element_count(jNode); return true; } +static void +jw_put_string_escape(JsonNode * jNode, char *string) +{ + int i; + + appendStringInfoChar(jNode->buf, '"'); + for (i = 0; string[i] != '\0'; i++) + { + switch (string[i]) + { + case '\"': + appendStringInfo(jNode->buf, "\\\""); + break; + case '\\': + appendStringInfo(jNode->buf, "\\\\"); + break; + case '\b': + appendStringInfo(jNode->buf, "\\b"); + break; + case '\f': + appendStringInfo(jNode->buf, "\\f"); + break; + case '\n': + appendStringInfo(jNode->buf, "\\n"); + break; + case '\r': + appendStringInfo(jNode->buf, "\\r"); + break; + case '\t': + appendStringInfo(jNode->buf, "\\t"); + break; + default: + appendStringInfoChar(jNode->buf, string[i]); + break; + } + } + appendStringInfoChar(jNode->buf, '"'); +} + /* for compatibility reasons we pack bool in int*/ bool jw_put_bool(JsonNode * jNode, char *key, bool value) -- 2.39.5