Commit b1b789df4203296a848fec6a3513f30efceb1a45

Authored by Jay Berkenbilt
1 parent 3490090f

Detect end of input inside an unfinished JSON string

fuzz/json_fuzzer_seed_corpus/9bc1baa450a0977fb3ac06c1ddb3fc2d4c05a5ce 0 → 100644
  1 +{"qpdf":[{},{"obj:1 0 R":{"stream":{"data":"
0 \ No newline at end of file 2 \ No newline at end of file
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;