aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJay Berkenbilt <ejb@ql.org>2024-02-06 21:12:41 +0100
committerJay Berkenbilt <ejb@ql.org>2024-02-06 21:12:41 +0100
commit3490090fbc7266dfcf7c80c6766d4d557b314292 (patch)
tree3701db07e037a796fa79a8ec2bd697efa17625f4
parent7ae095fa091af9a94e0e9bf140280a0519859d98 (diff)
downloadqpdf-3490090fbc7266dfcf7c80c6766d4d557b314292.tar.zst
Detect JSON object whose value is an indirect object
-rw-r--r--fuzz/json_fuzzer_seed_corpus/7865f715436bd6c3cdb6b073fcb44b297cb980971
-rw-r--r--fuzz/qtest/fuzz.test2
-rw-r--r--libqpdf/QPDF_json.cc4
-rw-r--r--qpdf/qtest/qpdf-json.test1
-rw-r--r--qpdf/qtest/qpdf/qjson-object-value-indirect.json68
-rw-r--r--qpdf/qtest/qpdf/qjson-object-value-indirect.out2
6 files changed, 77 insertions, 1 deletions
diff --git a/fuzz/json_fuzzer_seed_corpus/7865f715436bd6c3cdb6b073fcb44b297cb98097 b/fuzz/json_fuzzer_seed_corpus/7865f715436bd6c3cdb6b073fcb44b297cb98097
new file mode 100644
index 00000000..0500193d
--- /dev/null
+++ b/fuzz/json_fuzzer_seed_corpus/7865f715436bd6c3cdb6b073fcb44b297cb98097
@@ -0,0 +1 @@
+{"qpdf":[{},{"obj:1 0 R":{"value":"2 0 R" \ No newline at end of file
diff --git a/fuzz/qtest/fuzz.test b/fuzz/qtest/fuzz.test
index 4a20e5bf..28676339 100644
--- a/fuzz/qtest/fuzz.test
+++ b/fuzz/qtest/fuzz.test
@@ -16,7 +16,7 @@ my @fuzzers = (
['dct' => 1],
['flate' => 1],
['hex' => 1],
- ['json' => 38],
+ ['json' => 39],
['lzw' => 2],
['pngpredictor' => 1],
['runlength' => 6],
diff --git a/libqpdf/QPDF_json.cc b/libqpdf/QPDF_json.cc
index 502f2346..8326e6a5 100644
--- a/libqpdf/QPDF_json.cc
+++ b/libqpdf/QPDF_json.cc
@@ -441,6 +441,10 @@ QPDF::JSONReactor::containerEnd(JSON const& value)
void
QPDF::JSONReactor::replaceObject(QPDFObjectHandle&& replacement, JSON const& value)
{
+ if (replacement.isIndirect()) {
+ error(replacement.getParsedOffset(), "the value of an object may not be an indirect object reference");
+ return;
+ }
auto& tos = stack.back();
auto og = tos.object.getObjGen();
this->pdf.replaceObject(og, replacement);
diff --git a/qpdf/qtest/qpdf-json.test b/qpdf/qtest/qpdf-json.test
index 2f7bcd86..9542bccf 100644
--- a/qpdf/qtest/qpdf-json.test
+++ b/qpdf/qtest/qpdf-json.test
@@ -28,6 +28,7 @@ my @badfiles = (
'objects-not-dict',
'bad-object-key',
'object-not-dict',
+ 'object-value-indirect',
'stream-not-dict',
'stream-dict-not-dict',
'trailer-not-dict',
diff --git a/qpdf/qtest/qpdf/qjson-object-value-indirect.json b/qpdf/qtest/qpdf/qjson-object-value-indirect.json
new file mode 100644
index 00000000..107e99b5
--- /dev/null
+++ b/qpdf/qtest/qpdf/qjson-object-value-indirect.json
@@ -0,0 +1,68 @@
+{
+ "qpdf": [
+ {
+ "jsonversion": 2,
+ "pdfversion": "1.3",
+ "maxobjectid": 6
+ },
+ {
+ "obj:1 0 R": {
+ "value": "2 0 R"
+ },
+ "obj:2 0 R": {
+ "value": {
+ "/Count": 1,
+ "/Kids": [
+ "3 0 R"
+ ],
+ "/Type": "/Pages"
+ }
+ },
+ "obj:3 0 R": {
+ "value": {
+ "/Contents": "4 0 R",
+ "/MediaBox": [
+ 0,
+ 0,
+ 612,
+ 792
+ ],
+ "/Parent": "2 0 R",
+ "/Resources": {
+ "/Font": {
+ "/F1": "6 0 R"
+ },
+ "/ProcSet": "5 0 R"
+ },
+ "/Type": "/Page"
+ }
+ },
+ "obj:4 0 R": {
+ "stream": {
+ "data": "QlQKICAvRjEgMjQgVGYKICA3MiA3MjAgVGQKICAoUG90YXRvKSBUagpFVAo=",
+ "dict": {}
+ }
+ },
+ "obj:5 0 R": {
+ "value": [
+ "/PDF",
+ "/Text"
+ ]
+ },
+ "obj:6 0 R": {
+ "value": {
+ "/BaseFont": "/Helvetica",
+ "/Encoding": "/WinAnsiEncoding",
+ "/Subtype": "/Type1",
+ "/Type": "/Font"
+ }
+ },
+ "trailer": {
+ "value": {
+ "/Root": "1 0 R",
+ "/Size": 7
+ }
+ }
+ }
+ ]
+}
diff --git a/qpdf/qtest/qpdf/qjson-object-value-indirect.out b/qpdf/qtest/qpdf/qjson-object-value-indirect.out
new file mode 100644
index 00000000..cd702337
--- /dev/null
+++ b/qpdf/qtest/qpdf/qjson-object-value-indirect.out
@@ -0,0 +1,2 @@
+WARNING: qjson-object-value-indirect.json (obj:1 0 R): the value of an object may not be an indirect object reference
+qpdf: qjson-object-value-indirect.json: errors found in JSON