aboutsummaryrefslogtreecommitdiff
path: root/src/common/jsonapi.c
diff options
context:
space:
mode:
authorJohn Naylor <john.naylor@postgresql.org>2022-07-12 11:13:41 +0700
committerJohn Naylor <john.naylor@postgresql.org>2022-07-12 11:25:47 +0700
commitd3117fc1a3e87717a57be0153408e5387e265e1b (patch)
treed5054f87f409950725fd304332186a68825a53ef /src/common/jsonapi.c
parent3b00a944a9b3847fb02dae7c9ea62fe0b211b396 (diff)
downloadpostgresql-d3117fc1a3e87717a57be0153408e5387e265e1b.tar.gz
postgresql-d3117fc1a3e87717a57be0153408e5387e265e1b.zip
Fix out-of-bounds read in json_lex_string
Commit 3838fa269 added a lookahead loop to allow building strings multiple bytes at a time. This loop could exit because it reached the end of input, yet did not check for that before checking if we reached the end of a valid string. To fix, put the end of string check back in the outer loop. Per Valgrind animal skink
Diffstat (limited to 'src/common/jsonapi.c')
-rw-r--r--src/common/jsonapi.c18
1 files changed, 10 insertions, 8 deletions
diff --git a/src/common/jsonapi.c b/src/common/jsonapi.c
index 694417bb388..fefd1d24d90 100644
--- a/src/common/jsonapi.c
+++ b/src/common/jsonapi.c
@@ -686,6 +686,8 @@ json_lex_string(JsonLexContext *lex)
lex->token_terminator = s;
return JSON_INVALID_TOKEN;
}
+ else if (*s == '"')
+ break;
else if (*s == '\\')
{
/* OK, we have an escape character. */
@@ -870,14 +872,6 @@ json_lex_string(JsonLexContext *lex)
if (lex->strval != NULL)
appendBinaryStringInfo(lex->strval, s, p - s);
- if (*p == '"')
- {
- /* Hooray, we found the end of the string! */
- lex->prev_token_terminator = lex->token_terminator;
- lex->token_terminator = p + 1;
- return JSON_SUCCESS;
- }
-
/*
* s will be incremented at the top of the loop, so set it to just
* behind our lookahead position
@@ -885,6 +879,14 @@ json_lex_string(JsonLexContext *lex)
s = p - 1;
}
}
+
+ if (hi_surrogate != -1)
+ return JSON_UNICODE_LOW_SURROGATE;
+
+ /* Hooray, we found the end of the string! */
+ lex->prev_token_terminator = lex->token_terminator;
+ lex->token_terminator = s + 1;
+ return JSON_SUCCESS;
}
/*