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;
}