This new return path...
> + if (!tok_done)
> + {
> + if (lex->inc_state->is_last_chunk)
> + return JSON_INVALID_TOKEN;
...also needs to set the token pointers. See one approach in the
attached diff, which additionally asserts that we've consumed the
entire chunk in this case, along with a handful of new tests.
--Jacob
diff --git a/src/common/jsonapi.c b/src/common/jsonapi.c
index 4285b6557c..5babdd0e63 100644
--- a/src/common/jsonapi.c
+++ b/src/common/jsonapi.c
@@ -1378,10 +1378,16 @@ json_lex(JsonLexContext *lex)
if (!tok_done)
{
- if (lex->inc_state->is_last_chunk)
- return JSON_INVALID_TOKEN;
- else
+ /* We should have consumed the whole chunk in this
case. */
+ Assert(added == lex->input_length);
+
+ if (!lex->inc_state->is_last_chunk)
return JSON_INCOMPLETE;
+
+ /* json_errdetail() needs access to the accumulated
token. */
+ lex->token_start = ptok->data;
+ lex->token_terminator = ptok->data + ptok->len;
+ return JSON_INVALID_TOKEN;
}
lex->input += added;
diff --git a/src/test/modules/test_json_parser/t/002_inline.pl
b/src/test/modules/test_json_parser/t/002_inline.pl
index 7223287000..03e5d30187 100644
--- a/src/test/modules/test_json_parser/t/002_inline.pl
+++ b/src/test/modules/test_json_parser/t/002_inline.pl
@@ -42,7 +42,8 @@ sub test
test("number", "12345");
test("string", '"hello"');
-test("boolean", "false");
+test("false", "false");
+test("true", "true");
test("null", "null");
test("empty object", "{}");
test("empty array", "[]");
@@ -53,6 +54,9 @@ test("array with string", '["hello"]');
test("array with boolean", '[false]');
test("single pair", '{"key": "value"}');
test("heavily nested array", "[" x 3200 . "]" x 3200);
+test("serial escapes", '"\\\\\\\\\\\\\\\\"');
+test("interrupted escapes", '"\\\\\\"\\\\\\\\\\"\\\\"');
+test("whitespace", ' "" ');
test("unclosed empty object", "{", error => qr/input string ended
unexpectedly/);
test("bad key", "{{", error => qr/Expected string or "}", but found "\{"/);
@@ -75,5 +79,6 @@ test("smashed top-level scalar", "12zz", error => qr/Token
"12zz" is invalid/);
test("smashed scalar in array", "[12zz]", error => qr/Token "12zz" is
invalid/);
test("unknown escape sequence", '"hello\vworld"', error => qr/Escape sequence
"\\v" is invalid/);
test("unescaped control", "\"hello\tworld\"", error => qr/Character with value
0x09 must be escaped/);
+test("incorrect escape count", '"\\\\\\\\\\\\\\"', error => qr/Token
""\\\\\\\\\\\\\\"" is invalid/);
done_testing();