]> granicus.if.org Git - postgresql/commitdiff
Fix output of char node fields
authorPeter Eisentraut <peter_e@gmx.net>
Thu, 22 Jun 2017 02:57:23 +0000 (22:57 -0400)
committerPeter Eisentraut <peter_e@gmx.net>
Wed, 5 Jul 2017 14:51:54 +0000 (10:51 -0400)
WRITE_CHAR_FIELD() didn't do any escaping, so that for example a zero
byte would cause the whole output string to be truncated.  To fix, pass
the char through outToken(), so it is escaped like a string.  Adjust the
reading side to handle this.

src/backend/nodes/outfuncs.c
src/backend/nodes/readfuncs.c

index 3a23f0bb164b31d4ab6413b38d51bbd3ef27fef5..b0abe9ec10ff1a2a5ca3a39dee7105645830531c 100644 (file)
@@ -32,6 +32,8 @@
 #include "utils/datum.h"
 #include "utils/rel.h"
 
+static void outChar(StringInfo str, char c);
+
 
 /*
  * Macros to simplify output of different kinds of fields.  Use these
@@ -62,7 +64,8 @@
 
 /* Write a char field (ie, one ascii character) */
 #define WRITE_CHAR_FIELD(fldname) \
-       appendStringInfo(str, " :" CppAsString(fldname) " %c", node->fldname)
+       (appendStringInfo(str, " :" CppAsString(fldname) " "), \
+        outChar(str, node->fldname))
 
 /* Write an enumerated-type field as an integer code */
 #define WRITE_ENUM_FIELD(fldname, enumtype) \
@@ -140,6 +143,21 @@ outToken(StringInfo str, const char *s)
        }
 }
 
+/*
+ * Convert one char.  Goes through outToken() so that special characters are
+ * escaped.
+ */
+static void
+outChar(StringInfo str, char c)
+{
+       char            in[2];
+
+       in[0] = c;
+       in[1] = '\0';
+
+       outToken(str, in);
+}
+
 static void
 _outList(StringInfo str, const List *node)
 {
index 2988e8bd16d15829216acdfa7226d0c671e04798..1380703cbc661aa89c7cab2c39200fe740e660fd 100644 (file)
@@ -86,7 +86,8 @@
 #define READ_CHAR_FIELD(fldname) \
        token = pg_strtok(&length);             /* skip :fldname */ \
        token = pg_strtok(&length);             /* get field value */ \
-       local_node->fldname = token[0]
+       /* avoid overhead of calling debackslash() for one char */ \
+       local_node->fldname = (length == 0) ? '\0' : (token[0] == '\\' ? token[1] : token[0])
 
 /* Read an enumerated-type field that was written as an integer code */
 #define READ_ENUM_FIELD(fldname, enumtype) \