aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Eisentraut <peter_e@gmx.net>2017-06-21 22:57:23 -0400
committerPeter Eisentraut <peter_e@gmx.net>2017-07-05 10:51:54 -0400
commitd80e73f2293429cf8a0a13c243852379ec2e37e2 (patch)
treea54e87faf18d532fc23542084217496940d7ffe7
parent5191e357cf22e200a9baaf97bbe8a07ee2537537 (diff)
downloadpostgresql-d80e73f2293429cf8a0a13c243852379ec2e37e2.tar.gz
postgresql-d80e73f2293429cf8a0a13c243852379ec2e37e2.zip
Fix output of char node fields
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.
-rw-r--r--src/backend/nodes/outfuncs.c20
-rw-r--r--src/backend/nodes/readfuncs.c3
2 files changed, 21 insertions, 2 deletions
diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c
index 3a23f0bb164..b0abe9ec10f 100644
--- a/src/backend/nodes/outfuncs.c
+++ b/src/backend/nodes/outfuncs.c
@@ -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)
{
diff --git a/src/backend/nodes/readfuncs.c b/src/backend/nodes/readfuncs.c
index 2988e8bd16d..1380703cbc6 100644
--- a/src/backend/nodes/readfuncs.c
+++ b/src/backend/nodes/readfuncs.c
@@ -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) \