aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--TODO4
-rw-r--r--libqpdf/QPDF_json.cc24
-rw-r--r--qpdf/qpdf.testcov2
-rw-r--r--qpdf/qtest/qpdf-json.test68
-rw-r--r--qpdf/qtest/qpdf/duplicate-page-inherited-1-fixed.json96
-rw-r--r--qpdf/qtest/qpdf/duplicate-page-inherited-1-fixed.pdf142
-rw-r--r--qpdf/qtest/qpdf/duplicate-page-inherited-1.json112
-rw-r--r--qpdf/qtest/qpdf/duplicate-page-inherited-2-fixed.json104
-rw-r--r--qpdf/qtest/qpdf/duplicate-page-inherited-2-fixed.pdf153
-rw-r--r--qpdf/qtest/qpdf/duplicate-page-inherited-2.json125
-rw-r--r--qpdf/qtest/qpdf/duplicate-page-inherited-update.json31
-rw-r--r--qpdf/qtest/qpdf/duplicate-page-inherited-update2.json35
-rw-r--r--qpdf/qtest/qpdf/duplicate-page-inherited.out2
-rw-r--r--qpdf/qtest/qpdf/duplicate-page-inherited.pdf82
-rw-r--r--qpdf/qtest/qpdf/qjson-bad-pdf-version2.json2
-rw-r--r--qpdf/qtest/qpdf/qjson-bad-pdf-version2.out2
16 files changed, 980 insertions, 4 deletions
diff --git a/TODO b/TODO
index 9fdfff90..38f0ea92 100644
--- a/TODO
+++ b/TODO
@@ -71,10 +71,6 @@ JSON v2 fixes
* Rethink QPDF::writeJSON. Maybe provide a simpler overload?
-* When reading back in, we'll have to call
- pushInheritedAttributesToPage or getAllPages based on the values
- of the metadata.
-
* Support json v2 in the C API. At a minimum, write_json,
create_from_json, and update_from_json need to be there and should
take the same kinds of functions as the C API for logger.
diff --git a/libqpdf/QPDF_json.cc b/libqpdf/QPDF_json.cc
index f90096f5..213aa209 100644
--- a/libqpdf/QPDF_json.cc
+++ b/libqpdf/QPDF_json.cc
@@ -473,6 +473,30 @@ QPDF::JSONReactor::dictionaryItem(std::string const& key, JSON const& value)
QTC::TC("qpdf", "QPDF_json bad json version");
error(value.getStart(), "invalid JSON version (must be 2)");
}
+ } else if (key == "pushedinheritedpageresources") {
+ bool v;
+ if (value.getBool(v)) {
+ if ((!this->must_be_complete) && v) {
+ this->pdf.pushInheritedAttributesToPage();
+ }
+ } else {
+ QTC::TC("qpdf", "QPDF_json bad pushedinheritedpageresources");
+ error(
+ value.getStart(),
+ "pushedinheritedpageresources must be a boolean");
+ }
+ } else if (key == "calledgetallpages") {
+ bool v;
+ if (value.getBool(v)) {
+ if ((!this->must_be_complete) && v) {
+ this->pdf.getAllPages();
+ }
+ } else {
+ QTC::TC("qpdf", "QPDF_json bad calledgetallpages");
+ error(
+ value.getStart(),
+ "calledgetallpages must be a boolean");
+ }
} else {
// ignore unknown keys for forward compatibility and to
// skip keys we don't care about like "maxobjectid".
diff --git a/qpdf/qpdf.testcov b/qpdf/qpdf.testcov
index bfd3585f..f535b9ee 100644
--- a/qpdf/qpdf.testcov
+++ b/qpdf/qpdf.testcov
@@ -672,3 +672,5 @@ QPDF_json qpdf not array 0
QPDF_json more than two qpdf elements 0
QPDF_json missing json version 0
QPDF_json bad json version 0
+QPDF_json bad calledgetallpages 0
+QPDF_json bad pushedinheritedpageresources 0
diff --git a/qpdf/qtest/qpdf-json.test b/qpdf/qtest/qpdf-json.test
index abd9fa49..481cdca9 100644
--- a/qpdf/qtest/qpdf-json.test
+++ b/qpdf/qtest/qpdf-json.test
@@ -214,5 +214,73 @@ $td->runtest("update-from-json object description",
{$td->FILE => "test-90.out", $td->EXIT_STATUS => 0},
$td->NORMALIZE_NEWLINES);
+# Exercise pushedinheritedpageresources and calledgetallpages
+$n_tests += 12;
+$td->runtest("call getAllPages",
+ {$td->COMMAND =>
+ "qpdf --json-output duplicate-page-inherited.pdf" .
+ " --json-key=pages a.json"},
+ {$td->FILE => "duplicate-page-inherited.out",
+ $td->EXIT_STATUS => 3},
+ $td->NORMALIZE_NEWLINES);
+$td->runtest("check json (1)",
+ {$td->FILE => "a.json"},
+ {$td->FILE => "duplicate-page-inherited-1.json"},
+ $td->NORMALIZE_NEWLINES);
+$td->runtest("update (1)",
+ {$td->COMMAND =>
+ "qpdf" .
+ " --update-from-json=duplicate-page-inherited-update.json" .
+ " --json-output duplicate-page-inherited.pdf" .
+ " a.json"},
+ {$td->FILE => "duplicate-page-inherited.out",
+ $td->EXIT_STATUS => 3},
+ $td->NORMALIZE_NEWLINES);
+$td->runtest("check json (2)",
+ {$td->FILE => "a.json"},
+ {$td->FILE => "duplicate-page-inherited-1-fixed.json"},
+ $td->NORMALIZE_NEWLINES);
+$td->runtest("create PDF (1)",
+ {$td->COMMAND =>
+ "qpdf --qdf --static-id --json-input a.json a.pdf"},
+ {$td->STRING => "", $td->EXIT_STATUS => 0},
+ $td->NORMALIZE_NEWLINES);
+$td->runtest("check PDF (1)",
+ {$td->FILE => "a.pdf"},
+ {$td->FILE => "duplicate-page-inherited-1-fixed.pdf"});
+
+$td->runtest("call pushInheritedAttributesToPage",
+ {$td->COMMAND =>
+ "qpdf --json-output duplicate-page-inherited.pdf" .
+ " --json-key=pages --pages . -- a.json"},
+ {$td->FILE => "duplicate-page-inherited.out",
+ $td->EXIT_STATUS => 3},
+ $td->NORMALIZE_NEWLINES);
+$td->runtest("check json (2)",
+ {$td->FILE => "a.json"},
+ {$td->FILE => "duplicate-page-inherited-2.json"},
+ $td->NORMALIZE_NEWLINES);
+$td->runtest("update (2)",
+ {$td->COMMAND =>
+ "qpdf" .
+ " --update-from-json=duplicate-page-inherited-update2.json" .
+ " --json-output duplicate-page-inherited.pdf" .
+ " a.json"},
+ {$td->FILE => "duplicate-page-inherited.out",
+ $td->EXIT_STATUS => 3},
+ $td->NORMALIZE_NEWLINES);
+$td->runtest("check json (3)",
+ {$td->FILE => "a.json"},
+ {$td->FILE => "duplicate-page-inherited-2-fixed.json"},
+ $td->NORMALIZE_NEWLINES);
+$td->runtest("create PDF (2)",
+ {$td->COMMAND =>
+ "qpdf --qdf --static-id --json-input a.json a.pdf"},
+ {$td->STRING => "", $td->EXIT_STATUS => 0},
+ $td->NORMALIZE_NEWLINES);
+$td->runtest("check PDF (2)",
+ {$td->FILE => "a.pdf"},
+ {$td->FILE => "duplicate-page-inherited-2-fixed.pdf"});
+
cleanup();
$td->report($n_tests);
diff --git a/qpdf/qtest/qpdf/duplicate-page-inherited-1-fixed.json b/qpdf/qtest/qpdf/duplicate-page-inherited-1-fixed.json
new file mode 100644
index 00000000..77897a7c
--- /dev/null
+++ b/qpdf/qtest/qpdf/duplicate-page-inherited-1-fixed.json
@@ -0,0 +1,96 @@
+{
+ "qpdf": [
+ {
+ "jsonversion": 2,
+ "pdfversion": "1.3",
+ "pushedinheritedpageresources": false,
+ "calledgetallpages": true,
+ "maxobjectid": 8
+ },
+ {
+ "obj:1 0 R": {
+ "value": {
+ "/Pages": "2 0 R",
+ "/Type": "/Catalog"
+ }
+ },
+ "obj:2 0 R": {
+ "value": {
+ "/Count": 2,
+ "/Kids": [
+ "3 0 R"
+ ],
+ "/Resources": {
+ "/Font": {
+ "/F1": "6 0 R"
+ }
+ },
+ "/Type": "/Pages"
+ }
+ },
+ "obj:3 0 R": {
+ "value": {
+ "/Count": 2,
+ "/Kids": [
+ "4 0 R",
+ "7 0 R"
+ ],
+ "/Parent": "2 0 R",
+ "/Type": "/Pages"
+ }
+ },
+ "obj:4 0 R": {
+ "value": {
+ "/Contents": "5 0 R",
+ "/MediaBox": [
+ 0,
+ 0,
+ 612,
+ 792
+ ],
+ "/Parent": "3 0 R",
+ "/Type": "/Page"
+ }
+ },
+ "obj:5 0 R": {
+ "stream": {
+ "data": "QlQKICAvRjEgMjQgVGYKICA3MiA3MjAgVGQKICAoUG90YXRvKSBUagpFVAo=",
+ "dict": {}
+ }
+ },
+ "obj:6 0 R": {
+ "value": {
+ "/BaseFont": "/Helvetica",
+ "/Encoding": "/WinAnsiEncoding",
+ "/Subtype": "/Type1",
+ "/Type": "/Font"
+ }
+ },
+ "obj:7 0 R": {
+ "value": {
+ "/Contents": "8 0 R",
+ "/MediaBox": [
+ 0,
+ 0,
+ 612,
+ 792
+ ],
+ "/Parent": "3 0 R",
+ "/Type": "/Page"
+ }
+ },
+ "obj:8 0 R": {
+ "stream": {
+ "data": "QlQKICAvRjEgMjQgVGYKICA3MiA3MjAgVGQKICAoU2FsYWQpIFRqCkVUCg==",
+ "dict": {}
+ }
+ },
+ "trailer": {
+ "value": {
+ "/Root": "1 0 R",
+ "/Size": 7
+ }
+ }
+ }
+ ]
+}
diff --git a/qpdf/qtest/qpdf/duplicate-page-inherited-1-fixed.pdf b/qpdf/qtest/qpdf/duplicate-page-inherited-1-fixed.pdf
new file mode 100644
index 00000000..73b75947
--- /dev/null
+++ b/qpdf/qtest/qpdf/duplicate-page-inherited-1-fixed.pdf
@@ -0,0 +1,142 @@
+%PDF-1.3
+%¿÷¢þ
+%QDF-1.0
+
+%% Original object ID: 1 0
+1 0 obj
+<<
+ /Pages 2 0 R
+ /Type /Catalog
+>>
+endobj
+
+%% Original object ID: 2 0
+2 0 obj
+<<
+ /Count 2
+ /Kids [
+ 3 0 R
+ ]
+ /Resources <<
+ /Font <<
+ /F1 4 0 R
+ >>
+ >>
+ /Type /Pages
+>>
+endobj
+
+%% Original object ID: 3 0
+3 0 obj
+<<
+ /Count 2
+ /Kids [
+ 5 0 R
+ 6 0 R
+ ]
+ /Parent 2 0 R
+ /Type /Pages
+>>
+endobj
+
+%% Original object ID: 6 0
+4 0 obj
+<<
+ /BaseFont /Helvetica
+ /Encoding /WinAnsiEncoding
+ /Subtype /Type1
+ /Type /Font
+>>
+endobj
+
+%% Page 1
+%% Original object ID: 4 0
+5 0 obj
+<<
+ /Contents 7 0 R
+ /MediaBox [
+ 0
+ 0
+ 612
+ 792
+ ]
+ /Parent 3 0 R
+ /Type /Page
+>>
+endobj
+
+%% Page 2
+%% Original object ID: 7 0
+6 0 obj
+<<
+ /Contents 9 0 R
+ /MediaBox [
+ 0
+ 0
+ 612
+ 792
+ ]
+ /Parent 3 0 R
+ /Type /Page
+>>
+endobj
+
+%% Contents for page 1
+%% Original object ID: 5 0
+7 0 obj
+<<
+ /Length 8 0 R
+>>
+stream
+BT
+ /F1 24 Tf
+ 72 720 Td
+ (Potato) Tj
+ET
+endstream
+endobj
+
+8 0 obj
+44
+endobj
+
+%% Contents for page 2
+%% Original object ID: 8 0
+9 0 obj
+<<
+ /Length 10 0 R
+>>
+stream
+BT
+ /F1 24 Tf
+ 72 720 Td
+ (Salad) Tj
+ET
+endstream
+endobj
+
+10 0 obj
+43
+endobj
+
+xref
+0 11
+0000000000 65535 f
+0000000052 00000 n
+0000000133 00000 n
+0000000289 00000 n
+0000000414 00000 n
+0000000557 00000 n
+0000000710 00000 n
+0000000876 00000 n
+0000000975 00000 n
+0000001044 00000 n
+0000001143 00000 n
+trailer <<
+ /Root 1 0 R
+ /Size 11
+ /ID [<31415926535897932384626433832795><31415926535897932384626433832795>]
+>>
+startxref
+1163
+%%EOF
diff --git a/qpdf/qtest/qpdf/duplicate-page-inherited-1.json b/qpdf/qtest/qpdf/duplicate-page-inherited-1.json
new file mode 100644
index 00000000..cdfb502e
--- /dev/null
+++ b/qpdf/qtest/qpdf/duplicate-page-inherited-1.json
@@ -0,0 +1,112 @@
+{
+ "pages": [
+ {
+ "contents": [
+ "5 0 R"
+ ],
+ "images": [],
+ "label": null,
+ "object": "4 0 R",
+ "outlines": [],
+ "pageposfrom1": 1
+ },
+ {
+ "contents": [
+ "5 0 R"
+ ],
+ "images": [],
+ "label": null,
+ "object": "7 0 R",
+ "outlines": [],
+ "pageposfrom1": 2
+ }
+ ],
+ "qpdf": [
+ {
+ "jsonversion": 2,
+ "pdfversion": "1.3",
+ "pushedinheritedpageresources": false,
+ "calledgetallpages": true,
+ "maxobjectid": 7
+ },
+ {
+ "obj:1 0 R": {
+ "value": {
+ "/Pages": "2 0 R",
+ "/Type": "/Catalog"
+ }
+ },
+ "obj:2 0 R": {
+ "value": {
+ "/Count": 2,
+ "/Kids": [
+ "3 0 R"
+ ],
+ "/Resources": {
+ "/Font": {
+ "/F1": "6 0 R"
+ }
+ },
+ "/Type": "/Pages"
+ }
+ },
+ "obj:3 0 R": {
+ "value": {
+ "/Count": 2,
+ "/Kids": [
+ "4 0 R",
+ "7 0 R"
+ ],
+ "/Parent": "2 0 R",
+ "/Type": "/Pages"
+ }
+ },
+ "obj:4 0 R": {
+ "value": {
+ "/Contents": "5 0 R",
+ "/MediaBox": [
+ 0,
+ 0,
+ 612,
+ 792
+ ],
+ "/Parent": "3 0 R",
+ "/Type": "/Page"
+ }
+ },
+ "obj:5 0 R": {
+ "stream": {
+ "data": "QlQKICAvRjEgMjQgVGYKICA3MiA3MjAgVGQKICAoUG90YXRvKSBUagpFVAo=",
+ "dict": {}
+ }
+ },
+ "obj:6 0 R": {
+ "value": {
+ "/BaseFont": "/Helvetica",
+ "/Encoding": "/WinAnsiEncoding",
+ "/Subtype": "/Type1",
+ "/Type": "/Font"
+ }
+ },
+ "obj:7 0 R": {
+ "value": {
+ "/Contents": "5 0 R",
+ "/MediaBox": [
+ 0,
+ 0,
+ 612,
+ 792
+ ],
+ "/Parent": "3 0 R",
+ "/Type": "/Page"
+ }
+ },
+ "trailer": {
+ "value": {
+ "/Root": "1 0 R",
+ "/Size": 7
+ }
+ }
+ }
+ ]
+}
diff --git a/qpdf/qtest/qpdf/duplicate-page-inherited-2-fixed.json b/qpdf/qtest/qpdf/duplicate-page-inherited-2-fixed.json
new file mode 100644
index 00000000..e4073e49
--- /dev/null
+++ b/qpdf/qtest/qpdf/duplicate-page-inherited-2-fixed.json
@@ -0,0 +1,104 @@
+{
+ "qpdf": [
+ {
+ "jsonversion": 2,
+ "pdfversion": "1.3",
+ "pushedinheritedpageresources": true,
+ "calledgetallpages": true,
+ "maxobjectid": 9
+ },
+ {
+ "obj:1 0 R": {
+ "value": {
+ "/Pages": "2 0 R",
+ "/Type": "/Catalog"
+ }
+ },
+ "obj:2 0 R": {
+ "value": {
+ "/Count": 2,
+ "/Kids": [
+ "3 0 R"
+ ],
+ "/Type": "/Pages"
+ }
+ },
+ "obj:3 0 R": {
+ "value": {
+ "/Count": 2,
+ "/Kids": [
+ "4 0 R",
+ "7 0 R"
+ ],
+ "/Parent": "2 0 R",
+ "/Type": "/Pages"
+ }
+ },
+ "obj:4 0 R": {
+ "value": {
+ "/Contents": "5 0 R",
+ "/MediaBox": [
+ 0,
+ 0,
+ 612,
+ 792
+ ],
+ "/Parent": "3 0 R",
+ "/Resources": "8 0 R",
+ "/Type": "/Page"
+ }
+ },
+ "obj:5 0 R": {
+ "stream": {
+ "data": "QlQKICAvRjEgMjQgVGYKICA3MiA3MjAgVGQKICAoUG90YXRvKSBUagpFVAo=",
+ "dict": {}
+ }
+ },
+ "obj:6 0 R": {
+ "value": {
+ "/BaseFont": "/Helvetica",
+ "/Encoding": "/WinAnsiEncoding",
+ "/Subtype": "/Type1",
+ "/Type": "/Font"
+ }
+ },
+ "obj:7 0 R": {
+ "value": {
+ "/Contents": "9 0 R",
+ "/MediaBox": [
+ 0,
+ 0,
+ 612,
+ 792
+ ],
+ "/Parent": "2 0 R",
+ "/Resources": {
+ "/Font": {
+ "/F2": "6 0 R"
+ }
+ },
+ "/Type": "/Page"
+ }
+ },
+ "obj:8 0 R": {
+ "value": {
+ "/Font": {
+ "/F1": "6 0 R"
+ }
+ }
+ },
+ "obj:9 0 R": {
+ "stream": {
+ "data": "QlQKICAvRjIgMjQgVGYKICA3MiA3MjAgVGQKICAoU2FsYWQpIFRqCkVUCg==",
+ "dict": {}
+ }
+ },
+ "trailer": {
+ "value": {
+ "/Root": "1 0 R",
+ "/Size": 7
+ }
+ }
+ }
+ ]
+}
diff --git a/qpdf/qtest/qpdf/duplicate-page-inherited-2-fixed.pdf b/qpdf/qtest/qpdf/duplicate-page-inherited-2-fixed.pdf
new file mode 100644
index 00000000..46c746fe
--- /dev/null
+++ b/qpdf/qtest/qpdf/duplicate-page-inherited-2-fixed.pdf
@@ -0,0 +1,153 @@
+%PDF-1.3
+%¿÷¢þ
+%QDF-1.0
+
+%% Original object ID: 1 0
+1 0 obj
+<<
+ /Pages 2 0 R
+ /Type /Catalog
+>>
+endobj
+
+%% Original object ID: 2 0
+2 0 obj
+<<
+ /Count 2
+ /Kids [
+ 3 0 R
+ ]
+ /Type /Pages
+>>
+endobj
+
+%% Original object ID: 3 0
+3 0 obj
+<<
+ /Count 2
+ /Kids [
+ 4 0 R
+ 5 0 R
+ ]
+ /Parent 2 0 R
+ /Type /Pages
+>>
+endobj
+
+%% Page 1
+%% Original object ID: 4 0
+4 0 obj
+<<
+ /Contents 6 0 R
+ /MediaBox [
+ 0
+ 0
+ 612
+ 792
+ ]
+ /Parent 3 0 R
+ /Resources 8 0 R
+ /Type /Page
+>>
+endobj
+
+%% Page 2
+%% Original object ID: 7 0
+5 0 obj
+<<
+ /Contents 9 0 R
+ /MediaBox [
+ 0
+ 0
+ 612
+ 792
+ ]
+ /Parent 2 0 R
+ /Resources <<
+ /Font <<
+ /F2 11 0 R
+ >>
+ >>
+ /Type /Page
+>>
+endobj
+
+%% Contents for page 1
+%% Original object ID: 5 0
+6 0 obj
+<<
+ /Length 7 0 R
+>>
+stream
+BT
+ /F1 24 Tf
+ 72 720 Td
+ (Potato) Tj
+ET
+endstream
+endobj
+
+7 0 obj
+44
+endobj
+
+%% Original object ID: 8 0
+8 0 obj
+<<
+ /Font <<
+ /F1 11 0 R
+ >>
+>>
+endobj
+
+%% Contents for page 2
+%% Original object ID: 9 0
+9 0 obj
+<<
+ /Length 10 0 R
+>>
+stream
+BT
+ /F2 24 Tf
+ 72 720 Td
+ (Salad) Tj
+ET
+endstream
+endobj
+
+10 0 obj
+43
+endobj
+
+%% Original object ID: 6 0
+11 0 obj
+<<
+ /BaseFont /Helvetica
+ /Encoding /WinAnsiEncoding
+ /Subtype /Type1
+ /Type /Font
+>>
+endobj
+
+xref
+0 12
+0000000000 65535 f
+0000000052 00000 n
+0000000133 00000 n
+0000000232 00000 n
+0000000367 00000 n
+0000000539 00000 n
+0000000763 00000 n
+0000000862 00000 n
+0000000908 00000 n
+0000001011 00000 n
+0000001110 00000 n
+0000001157 00000 n
+trailer <<
+ /Root 1 0 R
+ /Size 12
+ /ID [<31415926535897932384626433832795><31415926535897932384626433832795>]
+>>
+startxref
+1264
+%%EOF
diff --git a/qpdf/qtest/qpdf/duplicate-page-inherited-2.json b/qpdf/qtest/qpdf/duplicate-page-inherited-2.json
new file mode 100644
index 00000000..5061b4a4
--- /dev/null
+++ b/qpdf/qtest/qpdf/duplicate-page-inherited-2.json
@@ -0,0 +1,125 @@
+{
+ "pages": [
+ {
+ "contents": [
+ "5 0 R"
+ ],
+ "images": [],
+ "label": null,
+ "object": "4 0 R",
+ "outlines": [],
+ "pageposfrom1": 1
+ },
+ {
+ "contents": [
+ "5 0 R"
+ ],
+ "images": [],
+ "label": null,
+ "object": "7 0 R",
+ "outlines": [],
+ "pageposfrom1": 2
+ }
+ ],
+ "qpdf": [
+ {
+ "jsonversion": 2,
+ "pdfversion": "1.3",
+ "pushedinheritedpageresources": true,
+ "calledgetallpages": true,
+ "maxobjectid": 8
+ },
+ {
+ "obj:1 0 R": {
+ "value": {
+ "/Pages": "2 0 R",
+ "/Type": "/Catalog"
+ }
+ },
+ "obj:2 0 R": {
+ "value": {
+ "/Count": 2,
+ "/Kids": [
+ "4 0 R",
+ "7 0 R"
+ ],
+ "/Type": "/Pages"
+ }
+ },
+ "obj:3 0 R": {
+ "value": {
+ "/Count": 2,
+ "/Kids": [
+ "4 0 R",
+ "7 0 R"
+ ],
+ "/Parent": "2 0 R",
+ "/Type": "/Pages"
+ }
+ },
+ "obj:4 0 R": {
+ "value": {
+ "/Contents": "5 0 R",
+ "/MediaBox": [
+ 0,
+ 0,
+ 612,
+ 792
+ ],
+ "/Parent": "2 0 R",
+ "/Resources": {
+ "/Font": {
+ "/F1": "6 0 R"
+ }
+ },
+ "/Type": "/Page"
+ }
+ },
+ "obj:5 0 R": {
+ "stream": {
+ "data": "QlQKICAvRjEgMjQgVGYKICA3MiA3MjAgVGQKICAoUG90YXRvKSBUagpFVAo=",
+ "dict": {}
+ }
+ },
+ "obj:6 0 R": {
+ "value": {
+ "/BaseFont": "/Helvetica",
+ "/Encoding": "/WinAnsiEncoding",
+ "/Subtype": "/Type1",
+ "/Type": "/Font"
+ }
+ },
+ "obj:7 0 R": {
+ "value": {
+ "/Contents": "5 0 R",
+ "/MediaBox": [
+ 0,
+ 0,
+ 612,
+ 792
+ ],
+ "/Parent": "2 0 R",
+ "/Resources": {
+ "/Font": {
+ "/F1": "6 0 R"
+ }
+ },
+ "/Type": "/Page"
+ }
+ },
+ "obj:8 0 R": {
+ "value": {
+ "/Font": {
+ "/F1": "6 0 R"
+ }
+ }
+ },
+ "trailer": {
+ "value": {
+ "/Root": "1 0 R",
+ "/Size": 7
+ }
+ }
+ }
+ ]
+}
diff --git a/qpdf/qtest/qpdf/duplicate-page-inherited-update.json b/qpdf/qtest/qpdf/duplicate-page-inherited-update.json
new file mode 100644
index 00000000..6a795941
--- /dev/null
+++ b/qpdf/qtest/qpdf/duplicate-page-inherited-update.json
@@ -0,0 +1,31 @@
+{
+ "qpdf": [
+ {
+ "jsonversion": 2,
+ "pushedinheritedpageresources": false,
+ "calledgetallpages": true,
+ "maxobjectid": 7
+ },
+ {
+ "obj:8 0 R": {
+ "stream": {
+ "data": "QlQKICAvRjEgMjQgVGYKICA3MiA3MjAgVGQKICAoU2FsYWQpIFRqCkVUCg==",
+ "dict": {}
+ }
+ },
+ "obj:7 0 R": {
+ "value": {
+ "/Contents": "8 0 R",
+ "/MediaBox": [
+ 0,
+ 0,
+ 612,
+ 792
+ ],
+ "/Parent": "3 0 R",
+ "/Type": "/Page"
+ }
+ }
+ }
+ ]
+}
diff --git a/qpdf/qtest/qpdf/duplicate-page-inherited-update2.json b/qpdf/qtest/qpdf/duplicate-page-inherited-update2.json
new file mode 100644
index 00000000..9607c5d6
--- /dev/null
+++ b/qpdf/qtest/qpdf/duplicate-page-inherited-update2.json
@@ -0,0 +1,35 @@
+{
+ "qpdf": [
+ {
+ "jsonversion": 2,
+ "pushedinheritedpageresources": true,
+ "calledgetallpages": true
+ },
+ {
+ "obj:9 0 R": {
+ "stream": {
+ "data": "QlQKICAvRjIgMjQgVGYKICA3MiA3MjAgVGQKICAoU2FsYWQpIFRqCkVUCg==",
+ "dict": {}
+ }
+ },
+ "obj:7 0 R": {
+ "value": {
+ "/Contents": "9 0 R",
+ "/MediaBox": [
+ 0,
+ 0,
+ 612,
+ 792
+ ],
+ "/Parent": "2 0 R",
+ "/Resources": {
+ "/Font": {
+ "/F2": "6 0 R"
+ }
+ },
+ "/Type": "/Page"
+ }
+ }
+ }
+ ]
+}
diff --git a/qpdf/qtest/qpdf/duplicate-page-inherited.out b/qpdf/qtest/qpdf/duplicate-page-inherited.out
new file mode 100644
index 00000000..15571c65
--- /dev/null
+++ b/qpdf/qtest/qpdf/duplicate-page-inherited.out
@@ -0,0 +1,2 @@
+WARNING: duplicate-page-inherited.pdf, object 3 0 at offset 202: kid 1 (from 0) appears more than once in the pages tree; creating a new page object as a copy
+qpdf: operation succeeded with warnings; resulting file may have some problems
diff --git a/qpdf/qtest/qpdf/duplicate-page-inherited.pdf b/qpdf/qtest/qpdf/duplicate-page-inherited.pdf
new file mode 100644
index 00000000..fceb786f
--- /dev/null
+++ b/qpdf/qtest/qpdf/duplicate-page-inherited.pdf
@@ -0,0 +1,82 @@
+%PDF-1.3
+1 0 obj
+<<
+ /Type /Catalog
+ /Pages 2 0 R
+>>
+endobj
+
+2 0 obj
+<<
+ /Type /Pages
+ /Resources <<
+ /Font <<
+ /F1 6 0 R
+ >>
+ >>
+ /Kids [
+ 3 0 R
+ ]
+ /Count 2
+>>
+endobj
+
+3 0 obj
+<<
+ /Type /Pages
+ /Parent 2 0 R
+ /Kids [
+ 4 0 R
+ 4 0 R
+ ]
+ /Count 2
+>>
+endobj
+
+4 0 obj
+<<
+ /Type /Page
+ /Parent 3 0 R
+ /MediaBox [0 0 612 792]
+ /Contents 5 0 R
+>>
+endobj
+
+5 0 obj
+<<
+ /Length 44
+>>
+stream
+BT
+ /F1 24 Tf
+ 72 720 Td
+ (Potato) Tj
+ET
+endstream
+endobj
+
+6 0 obj
+<<
+ /Type /Font
+ /Subtype /Type1
+ /BaseFont /Helvetica
+ /Encoding /WinAnsiEncoding
+>>
+endobj
+
+xref
+0 7
+0000000000 65535 f
+0000000009 00000 n
+0000000063 00000 n
+0000000192 00000 n
+0000000290 00000 n
+0000000386 00000 n
+0000000482 00000 n
+trailer <<
+ /Size 7
+ /Root 1 0 R
+>>
+startxref
+588
+%%EOF
diff --git a/qpdf/qtest/qpdf/qjson-bad-pdf-version2.json b/qpdf/qtest/qpdf/qjson-bad-pdf-version2.json
index f70cfb52..b15a60bd 100644
--- a/qpdf/qtest/qpdf/qjson-bad-pdf-version2.json
+++ b/qpdf/qtest/qpdf/qjson-bad-pdf-version2.json
@@ -3,6 +3,8 @@
{
"jsonversion": 850,
"pdfversion": [],
+ "calledgetallpages": 3,
+ "pushedinheritedpageresources": "potato",
"maxobjectid": 6
},
{
diff --git a/qpdf/qtest/qpdf/qjson-bad-pdf-version2.out b/qpdf/qtest/qpdf/qjson-bad-pdf-version2.out
index 65be40ca..9bc88ff4 100644
--- a/qpdf/qtest/qpdf/qjson-bad-pdf-version2.out
+++ b/qpdf/qtest/qpdf/qjson-bad-pdf-version2.out
@@ -1,3 +1,5 @@
WARNING: qjson-bad-pdf-version2.json (offset 41): invalid JSON version (must be 2)
WARNING: qjson-bad-pdf-version2.json (offset 66): invalid PDF version (must be x.y)
+WARNING: qjson-bad-pdf-version2.json (offset 97): calledgetallpages must be a boolean
+WARNING: qjson-bad-pdf-version2.json (offset 138): pushedinheritedpageresources must be a boolean
qpdf: qjson-bad-pdf-version2.json: errors found in JSON