aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJay Berkenbilt <ejb@ql.org>2024-02-06 21:30:29 +0100
committerJay Berkenbilt <ejb@ql.org>2024-02-06 21:30:29 +0100
commitb1b789df4203296a848fec6a3513f30efceb1a45 (patch)
treee1a506f8a74be0f502b05ce0f17c1816d162c129
parent3490090fbc7266dfcf7c80c6766d4d557b314292 (diff)
downloadqpdf-b1b789df4203296a848fec6a3513f30efceb1a45.tar.zst
Detect end of input inside an unfinished JSON string
-rw-r--r--fuzz/json_fuzzer_seed_corpus/9bc1baa450a0977fb3ac06c1ddb3fc2d4c05a5ce1
-rw-r--r--fuzz/qtest/fuzz.test2
-rw-r--r--libqpdf/JSON.cc5
-rw-r--r--libtests/json.cc6
4 files changed, 11 insertions, 3 deletions
diff --git a/fuzz/json_fuzzer_seed_corpus/9bc1baa450a0977fb3ac06c1ddb3fc2d4c05a5ce b/fuzz/json_fuzzer_seed_corpus/9bc1baa450a0977fb3ac06c1ddb3fc2d4c05a5ce
new file mode 100644
index 00000000..09495bc1
--- /dev/null
+++ b/fuzz/json_fuzzer_seed_corpus/9bc1baa450a0977fb3ac06c1ddb3fc2d4c05a5ce
@@ -0,0 +1 @@
+{"qpdf":[{},{"obj:1 0 R":{"stream":{"data":" \ No newline at end of file
diff --git a/fuzz/qtest/fuzz.test b/fuzz/qtest/fuzz.test
index 28676339..7235140d 100644
--- a/fuzz/qtest/fuzz.test
+++ b/fuzz/qtest/fuzz.test
@@ -16,7 +16,7 @@ my @fuzzers = (
['dct' => 1],
['flate' => 1],
['hex' => 1],
- ['json' => 39],
+ ['json' => 40],
['lzw' => 2],
['pngpredictor' => 1],
['runlength' => 6],
diff --git a/libqpdf/JSON.cc b/libqpdf/JSON.cc
index 28f451a9..27405df7 100644
--- a/libqpdf/JSON.cc
+++ b/libqpdf/JSON.cc
@@ -628,6 +628,7 @@ namespace
ls_number_e_sign,
ls_alpha,
ls_string,
+ ls_after_string,
ls_backslash,
ls_u4,
ls_begin_array,
@@ -1039,7 +1040,7 @@ JSONParser::getToken()
"JSON: offset " + std::to_string(high_offset) +
": UTF-16 high surrogate not followed by low surrogate");
}
- ignore();
+ ignore(ls_after_string);
return;
} else if (*p == '\\') {
ignore(ls_backslash);
@@ -1234,7 +1235,7 @@ JSONParser::handleToken()
}
break;
- case ls_string:
+ case ls_after_string:
if (parser_state == ps_dict_begin || parser_state == ps_dict_after_comma) {
dict_key = token;
dict_key_offset = token_start;
diff --git a/libtests/json.cc b/libtests/json.cc
index e84ef0a0..4f4cff8e 100644
--- a/libtests/json.cc
+++ b/libtests/json.cc
@@ -134,6 +134,12 @@ test_main()
" \"normal\": \"string\"\n"
"}");
+ try {
+ JSON::parse("\"");
+ assert(false);
+ } catch (std::runtime_error&) {
+ }
+
// Check default constructed JSON object (order as per JSON.hh).
JSON uninitialized;
std::string ws;