Commit b1b789df4203296a848fec6a3513f30efceb1a45
1 parent
3490090f
Detect end of input inside an unfinished JSON string
Showing
4 changed files
with
11 additions
and
3 deletions
fuzz/json_fuzzer_seed_corpus/9bc1baa450a0977fb3ac06c1ddb3fc2d4c05a5ce
0 → 100644
fuzz/qtest/fuzz.test
| @@ -16,7 +16,7 @@ my @fuzzers = ( | @@ -16,7 +16,7 @@ my @fuzzers = ( | ||
| 16 | ['dct' => 1], | 16 | ['dct' => 1], |
| 17 | ['flate' => 1], | 17 | ['flate' => 1], |
| 18 | ['hex' => 1], | 18 | ['hex' => 1], |
| 19 | - ['json' => 39], | 19 | + ['json' => 40], |
| 20 | ['lzw' => 2], | 20 | ['lzw' => 2], |
| 21 | ['pngpredictor' => 1], | 21 | ['pngpredictor' => 1], |
| 22 | ['runlength' => 6], | 22 | ['runlength' => 6], |
libqpdf/JSON.cc
| @@ -628,6 +628,7 @@ namespace | @@ -628,6 +628,7 @@ namespace | ||
| 628 | ls_number_e_sign, | 628 | ls_number_e_sign, |
| 629 | ls_alpha, | 629 | ls_alpha, |
| 630 | ls_string, | 630 | ls_string, |
| 631 | + ls_after_string, | ||
| 631 | ls_backslash, | 632 | ls_backslash, |
| 632 | ls_u4, | 633 | ls_u4, |
| 633 | ls_begin_array, | 634 | ls_begin_array, |
| @@ -1039,7 +1040,7 @@ JSONParser::getToken() | @@ -1039,7 +1040,7 @@ JSONParser::getToken() | ||
| 1039 | "JSON: offset " + std::to_string(high_offset) + | 1040 | "JSON: offset " + std::to_string(high_offset) + |
| 1040 | ": UTF-16 high surrogate not followed by low surrogate"); | 1041 | ": UTF-16 high surrogate not followed by low surrogate"); |
| 1041 | } | 1042 | } |
| 1042 | - ignore(); | 1043 | + ignore(ls_after_string); |
| 1043 | return; | 1044 | return; |
| 1044 | } else if (*p == '\\') { | 1045 | } else if (*p == '\\') { |
| 1045 | ignore(ls_backslash); | 1046 | ignore(ls_backslash); |
| @@ -1234,7 +1235,7 @@ JSONParser::handleToken() | @@ -1234,7 +1235,7 @@ JSONParser::handleToken() | ||
| 1234 | } | 1235 | } |
| 1235 | break; | 1236 | break; |
| 1236 | 1237 | ||
| 1237 | - case ls_string: | 1238 | + case ls_after_string: |
| 1238 | if (parser_state == ps_dict_begin || parser_state == ps_dict_after_comma) { | 1239 | if (parser_state == ps_dict_begin || parser_state == ps_dict_after_comma) { |
| 1239 | dict_key = token; | 1240 | dict_key = token; |
| 1240 | dict_key_offset = token_start; | 1241 | dict_key_offset = token_start; |
libtests/json.cc
| @@ -134,6 +134,12 @@ test_main() | @@ -134,6 +134,12 @@ test_main() | ||
| 134 | " \"normal\": \"string\"\n" | 134 | " \"normal\": \"string\"\n" |
| 135 | "}"); | 135 | "}"); |
| 136 | 136 | ||
| 137 | + try { | ||
| 138 | + JSON::parse("\""); | ||
| 139 | + assert(false); | ||
| 140 | + } catch (std::runtime_error&) { | ||
| 141 | + } | ||
| 142 | + | ||
| 137 | // Check default constructed JSON object (order as per JSON.hh). | 143 | // Check default constructed JSON object (order as per JSON.hh). |
| 138 | JSON uninitialized; | 144 | JSON uninitialized; |
| 139 | std::string ws; | 145 | std::string ws; |