Although the following problem does not seem to be exposed in the core, I
think it's still a problem to fix. (I've hit it when implementing a custom
parser for extension configuration file.)

If makeJsonLexContextCstringLen() is passed need_escapes=false,
JsonLexContext.strval is not initialized, and in turn, functions of
JsonSemAction which should receive the string token value
(e.g. object_field_start) receive NULL.

Attached is a patch that fixes the problem. If this approach is acceptable,
then it'd probably be worth to also rename the JsonLexContext.strval field to
something that recalls the "de-escaping", e.g. "noesc"?

-- 
Antonin Houska
Web: https://www.cybertec-postgresql.com

diff --git a/src/backend/utils/adt/json.c b/src/backend/utils/adt/json.c
index 26d293709a..2ef16fb089 100644
--- a/src/backend/utils/adt/json.c
+++ b/src/backend/utils/adt/json.c
@@ -142,17 +142,26 @@ lex_accept(JsonLexContext *lex, JsonTokenType token, char **lexeme)
 	{
 		if (lexeme != NULL)
 		{
-			if (lex->token_type == JSON_TOKEN_STRING)
-			{
-				if (lex->strval != NULL)
-					*lexeme = pstrdup(lex->strval->data);
-			}
+			if (lex->token_type == JSON_TOKEN_STRING && lex->strval != NULL)
+				*lexeme = pstrdup(lex->strval->data);
 			else
 			{
 				int			len = (lex->token_terminator - lex->token_start);
-				char	   *tokstr = palloc(len + 1);
+				char	*src = lex->token_start;
+				char	   *tokstr;
+
+				/* String token should be quoted. */
+				if (lex->token_type == JSON_TOKEN_STRING)
+				{
+					Assert(len >= 2);
+					Assert(src[0] == '"' && src[len - 1] == '"');
+
+					src++;
+					len -= 2;
+				}
 
-				memcpy(tokstr, lex->token_start, len);
+				tokstr = palloc(len + 1);
+				memcpy(tokstr, src, len);
 				tokstr[len] = '\0';
 				*lexeme = tokstr;
 			}

Reply via email to