diff options
author | John Naylor <john.naylor@postgresql.org> | 2022-07-12 11:13:41 +0700 |
---|---|---|
committer | John Naylor <john.naylor@postgresql.org> | 2022-07-12 11:25:47 +0700 |
commit | d3117fc1a3e87717a57be0153408e5387e265e1b (patch) | |
tree | d5054f87f409950725fd304332186a68825a53ef /src/common/jsonapi.c | |
parent | 3b00a944a9b3847fb02dae7c9ea62fe0b211b396 (diff) | |
download | postgresql-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.c | 18 |
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; } /* |