Fix json_writer did not properly encode special characters.
authorBo Peng <[email protected]>
Thu, 1 May 2025 02:36:55 +0000 (11:36 +0900)
committerBo Peng <[email protected]>
Thu, 1 May 2025 02:36:55 +0000 (11:36 +0900)
Pgpool would crash when the watchdog was enabled if wd_authkey contained special characters (e.g., a backslash).

The  was originally created by Martijn van Duren and revised by Bo Peng.

src/utils/json_writer.c

index 1f7133843f2ea1cfdb17857e2e8068a1c8fb3f24..7737390ce07bd52afef78961556b1e6f4fdc9f47 100644 (file)
@@ -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)