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();

Reply via email to