[pgpool-hackers: 4576] Re: BUG: json_writer doesn't properly encode special characters

Bo Peng pengbo at sraoss.co.jp
Thu Apr 10 14:40:15 JST 2025


Hi,

Thank you for reporting this bug.

I have been able to reproduce the issue.
I will test your patch and provide feedback shortly.

________________________________________
差出人: pgpool-hackers <pgpool-hackers-bounces at pgpool.net> が Martijn van Duren <pgpool at list.imperialat.at> の代理で送信
送信日時: 2025年4月10日 7:26
宛先: pgpool-hackers at pgpool.net
件名: [pgpool-hackers: 4575] BUG: json_writer doesn't properly encode     special characters

Hello all,

I'm new to pgpool and am currently playing around with it to see if it
suits my needs. While playing around with it (on OpenBSD) I noticed that
pgpool crashed when enabling watchdog. Looking at the logs I found:
WARNING:  authentication failed
DETAIL:  invalid IPC key
which made me make a ktrace, where I saw that the backslash that I added
to my (randomly generated) wd_authkey wasn't escaped inside the json
object, resulting in it being consumed by json.c's json_parse_ex().

The diff adds all the cases as defined in json_parse_ex()' flag_escaped
case, with the addition of '\' and '"', and the exception of \u, because
I don't have nor see the need. Quickly spun together and lightly tested,
but I expect it to be okay.

Test was done with a locally updated package of 4.6.0, and not OpenBSD's
default package, which currently is still at 3.7.18. I plan to push the
update once I'm comfortable enough with the tools. There's also a couple
of local diffs to make things build on OpenBSD, which could probably be
upstreamed as well. But let's first get this all platform bug out of the
way.

Sincerely,

Martijn van Duren

diff /home/martijn/src/pgpool2
path + /home/martijn/src/pgpool2
commit - d766e4a812f2aa78bfc946449620c31e416958a4
blob - 1f7133843f2ea1cfdb17857e2e8068a1c8fb3f24
file + src/utils/json_writer.c
--- src/utils/json_writer.c
+++ 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,50 @@ 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)

_______________________________________________
pgpool-hackers mailing list
pgpool-hackers at pgpool.net
http://www.pgpool.net/mailman/listinfo/pgpool-hackers


More information about the pgpool-hackers mailing list