aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJay Berkenbilt <ejb@ql.org>2022-07-31 01:29:55 +0200
committerJay Berkenbilt <ejb@ql.org>2022-07-31 16:32:55 +0200
commitd01c4f8819ea93797784c19ecdd623eb41f2a8b4 (patch)
tree28d5fef20279428e5a208f40183d0288ff0742af
parentbb96499b613265b3d9cf2146af09283a4b99ef13 (diff)
downloadqpdf-d01c4f8819ea93797784c19ecdd623eb41f2a8b4.tar.zst
Change --json-output format
from "qpdf-v2" to "qpdf": [..., ...]
-rw-r--r--TODO6
-rw-r--r--cSpell.json2
-rw-r--r--include/qpdf/QPDF.hh3
-rw-r--r--libqpdf/QPDFJob.cc3
-rw-r--r--libqpdf/QPDF_json.cc117
-rw-r--r--manual/json.rst48
-rw-r--r--qpdf/qpdf.testcov4
-rw-r--r--qpdf/qtest/qpdf-json.test2
-rw-r--r--qpdf/qtest/qpdf/exp-large-json.json15
-rw-r--r--qpdf/qtest/qpdf/json-bad-data-json-file-v2.out15
-rw-r--r--qpdf/qtest/qpdf/json-bad-data-json-inline-v2.out15
-rw-r--r--qpdf/qtest/qpdf/json-image-streams-all-file-v2.out15
-rw-r--r--qpdf/qtest/qpdf/json-image-streams-generalized-file-v2.out15
-rw-r--r--qpdf/qtest/qpdf/json-image-streams-generalized-inline-v2.out15
-rw-r--r--qpdf/qtest/qpdf/json-image-streams-none-file-v2.out15
-rw-r--r--qpdf/qtest/qpdf/json-image-streams-none-inline-v2.out15
-rw-r--r--qpdf/qtest/qpdf/json-image-streams-specialized-file-v2.out15
-rw-r--r--qpdf/qtest/qpdf/json-image-streams-specialized-inline-v2.out15
-rw-r--r--qpdf/qtest/qpdf/manual-qpdf-json-out.json15
-rw-r--r--qpdf/qtest/qpdf/manual-qpdf-json-pdf.json15
-rw-r--r--qpdf/qtest/qpdf/manual-qpdf-json.json25
-rw-r--r--qpdf/qtest/qpdf/minimal-json-file-2.out15
-rw-r--r--qpdf/qtest/qpdf/minimal-json-file.out15
-rw-r--r--qpdf/qtest/qpdf/qjson-bad-data.json13
-rw-r--r--qpdf/qtest/qpdf/qjson-bad-datafile.json13
-rw-r--r--qpdf/qtest/qpdf/qjson-bad-object-key.json13
-rw-r--r--qpdf/qtest/qpdf/qjson-bad-object-key.out2
-rw-r--r--qpdf/qtest/qpdf/qjson-bad-pdf-version1.json13
-rw-r--r--qpdf/qtest/qpdf/qjson-bad-pdf-version1.out3
-rw-r--r--qpdf/qtest/qpdf/qjson-bad-pdf-version2.json13
-rw-r--r--qpdf/qtest/qpdf/qjson-bad-pdf-version2.out3
-rw-r--r--qpdf/qtest/qpdf/qjson-missing-objects.json11
-rw-r--r--qpdf/qtest/qpdf/qjson-missing-objects.out2
-rw-r--r--qpdf/qtest/qpdf/qjson-missing-trailer.json13
-rw-r--r--qpdf/qtest/qpdf/qjson-missing-trailer.out2
-rw-r--r--qpdf/qtest/qpdf/qjson-no-pdf-version.json10
-rw-r--r--qpdf/qtest/qpdf/qjson-no-pdf-version.out3
-rw-r--r--qpdf/qtest/qpdf/qjson-obj-key-errors.json13
-rw-r--r--qpdf/qtest/qpdf/qjson-obj-key-errors.out12
-rw-r--r--qpdf/qtest/qpdf/qjson-object-not-dict.json13
-rw-r--r--qpdf/qtest/qpdf/qjson-object-not-dict.out2
-rw-r--r--qpdf/qtest/qpdf/qjson-objects-not-dict.json11
-rw-r--r--qpdf/qtest/qpdf/qjson-objects-not-dict.out4
-rw-r--r--qpdf/qtest/qpdf/qjson-qpdf-array-too-long.json72
-rw-r--r--qpdf/qtest/qpdf/qjson-qpdf-array-too-long.out2
-rw-r--r--qpdf/qtest/qpdf/qjson-qpdf-not-array.json5
-rw-r--r--qpdf/qtest/qpdf/qjson-qpdf-not-array.out5
-rw-r--r--qpdf/qtest/qpdf/qjson-stream-dict-not-dict.json11
-rw-r--r--qpdf/qtest/qpdf/qjson-stream-dict-not-dict.out8
-rw-r--r--qpdf/qtest/qpdf/qjson-stream-not-dict.json11
-rw-r--r--qpdf/qtest/qpdf/qjson-stream-not-dict.out4
-rw-r--r--qpdf/qtest/qpdf/qjson-trailer-not-dict.json13
-rw-r--r--qpdf/qtest/qpdf/qjson-trailer-not-dict.out2
-rw-r--r--qpdf/qtest/qpdf/qjson-trailer-stream.json13
-rw-r--r--qpdf/qtest/qpdf/qjson-trailer-stream.out2
-rw-r--r--qpdf/qtest/qpdf/qpdf-json-update-errors.json9
-rw-r--r--qpdf/qtest/qpdf/replace-with-stream.json13
-rw-r--r--qpdf/qtest/qpdf/test-89.out8
-rw-r--r--qpdf/qtest/qpdf/test-90.out6
-rw-r--r--qpdf/qtest/qpdf/update-from-json-errors.out6
-rw-r--r--qpdf/qtest/qpdf/update-stream-data.json13
-rw-r--r--qpdf/qtest/qpdf/update-stream-dict-only.json13
-rw-r--r--qpdf/qtest/qpdf/various-updates.json13
63 files changed, 569 insertions, 249 deletions
diff --git a/TODO b/TODO
index 61de004d..3830a938 100644
--- a/TODO
+++ b/TODO
@@ -84,15 +84,13 @@ JSON v2 fixes
"qpdf": [
{
"jsonversion": 2,
+ "pdfversion": "1.3",
"pushedinheritedpageresources": false,
"calledgetallpages": false,
"maxobjectid": 10
},
{
- "pdfversion": "1.3",
- "objects": {
- ...
- }
+ ... objects ...
}
]
}
diff --git a/cSpell.json b/cSpell.json
index 507ef610..6251d984 100644
--- a/cSpell.json
+++ b/cSpell.json
@@ -47,6 +47,7 @@
"bufpl",
"bufsize",
"buildrules",
+ "calledgetallpages",
"ccase",
"ccitt",
"cdef",
@@ -369,6 +370,7 @@
"programfiles",
"programlisting",
"proxied",
+ "pushedinheritedpageresources",
"putu",
"pval",
"pytest",
diff --git a/include/qpdf/QPDF.hh b/include/qpdf/QPDF.hh
index 639e16c4..943528bd 100644
--- a/include/qpdf/QPDF.hh
+++ b/include/qpdf/QPDF.hh
@@ -1072,6 +1072,7 @@ class QPDF
st_initial,
st_top,
st_qpdf,
+ st_qpdf_meta,
st_objects,
st_trailer,
st_object_top,
@@ -1097,7 +1098,9 @@ class QPDF
bool errors;
bool parse_error;
bool saw_qpdf;
+ bool saw_qpdf_meta;
bool saw_objects;
+ bool saw_json_version;
bool saw_pdf_version;
bool saw_trailer;
state_e state;
diff --git a/libqpdf/QPDFJob.cc b/libqpdf/QPDFJob.cc
index ae717218..e09c0d74 100644
--- a/libqpdf/QPDFJob.cc
+++ b/libqpdf/QPDFJob.cc
@@ -1741,6 +1741,9 @@ QPDFJob::json_out_schema_v1()
void
QPDFJob::doJSON(QPDF& pdf, Pipeline* p)
{
+ // qpdf guarantees that no new top-level keys whose names start
+ // with "xdata" will be added. These are reserved for users.
+
std::string captured_json;
std::shared_ptr<Pl_String> pl_str;
if (this->m->test_json_schema) {
diff --git a/libqpdf/QPDF_json.cc b/libqpdf/QPDF_json.cc
index 81f21f8a..9ecb1b31 100644
--- a/libqpdf/QPDF_json.cc
+++ b/libqpdf/QPDF_json.cc
@@ -226,7 +226,9 @@ QPDF::JSONReactor::JSONReactor(
errors(false),
parse_error(false),
saw_qpdf(false),
+ saw_qpdf_meta(false),
saw_objects(false),
+ saw_json_version(false),
saw_pdf_version(false),
saw_trailer(false),
state(st_initial),
@@ -292,17 +294,21 @@ QPDF::JSONReactor::containerEnd(JSON const& value)
QTC::TC("qpdf", "QPDF_json missing qpdf");
error(0, "\"qpdf\" object was not seen");
} else {
+ if (!this->saw_json_version) {
+ QTC::TC("qpdf", "QPDF_json missing json version");
+ error(0, "\"qpdf[0].jsonversion\" was not seen");
+ }
if (must_be_complete && !this->saw_pdf_version) {
QTC::TC("qpdf", "QPDF_json missing pdf version");
- error(0, "\"qpdf-v2.pdfversion\" was not seen");
+ error(0, "\"qpdf[0].pdfversion\" was not seen");
}
if (!this->saw_objects) {
QTC::TC("qpdf", "QPDF_json missing objects");
- error(0, "\"qpdf-v2.objects\" was not seen");
+ error(0, "\"qpdf[1]\" was not seen");
} else {
if (must_be_complete && !this->saw_trailer) {
QTC::TC("qpdf", "QPDF_json missing trailer");
- error(0, "\"qpdf-v2.objects.trailer\" was not seen");
+ error(0, "\"qpdf[1].trailer\" was not seen");
}
}
}
@@ -421,16 +427,22 @@ QPDF::JSONReactor::dictionaryItem(std::string const& key, JSON const& value)
QTC::TC("qpdf", "QPDF_json ignoring in st_ignore");
// ignore
} else if (state == st_top) {
- if (key == "qpdf-v2") {
+ if (key == "qpdf") {
this->saw_qpdf = true;
- nestedState(key, value, st_qpdf);
+ if (!value.isArray()) {
+ QTC::TC("qpdf", "QPDF_json qpdf not array");
+ error(value.getStart(), "\"qpdf\" must be an array");
+ next_state = st_ignore;
+ parse_error = true;
+ } else {
+ next_state = st_qpdf;
+ }
} else {
- // Ignore all other fields. We explicitly allow people to
- // add other top-level keys for their own use.
+ // Ignore all other fields.
QTC::TC("qpdf", "QPDF_json ignoring unknown top-level key");
next_state = st_ignore;
}
- } else if (state == st_qpdf) {
+ } else if (state == st_qpdf_meta) {
if (key == "pdfversion") {
this->saw_pdf_version = true;
bool version_okay = false;
@@ -447,9 +459,20 @@ QPDF::JSONReactor::dictionaryItem(std::string const& key, JSON const& value)
QTC::TC("qpdf", "QPDF_json bad pdf version");
error(value.getStart(), "invalid PDF version (must be x.y)");
}
- } else if (key == "objects") {
- this->saw_objects = true;
- nestedState(key, value, st_objects);
+ } else if (key == "jsonversion") {
+ this->saw_json_version = true;
+ bool version_okay = false;
+ std::string v;
+ if (value.getNumber(v)) {
+ std::string version;
+ if (QUtil::string_to_int(v.c_str()) == 2) {
+ version_okay = true;
+ }
+ }
+ if (!version_okay) {
+ QTC::TC("qpdf", "QPDF_json bad json version");
+ error(value.getStart(), "invalid JSON version (must be 2)");
+ }
} else {
// ignore unknown keys for forward compatibility and to
// skip keys we don't care about like "maxobjectid".
@@ -601,6 +624,20 @@ QPDF::JSONReactor::dictionaryItem(std::string const& key, JSON const& value)
bool
QPDF::JSONReactor::arrayItem(JSON const& value)
{
+ if (state == st_qpdf) {
+ if (!this->saw_qpdf_meta) {
+ this->saw_qpdf_meta = true;
+ nestedState("qpdf[0]", value, st_qpdf_meta);
+ } else if (!this->saw_objects) {
+ this->saw_objects = true;
+ nestedState("qpdf[1]", value, st_objects);
+ } else {
+ QTC::TC("qpdf", "QPDF_json more than two qpdf elements");
+ error(value.getStart(), "\"qpdf\" must have two elements");
+ next_state = st_ignore;
+ parse_error = true;
+ }
+ }
if (state == st_object) {
if (!parse_error) {
auto tos = object_stack.back();
@@ -771,30 +808,60 @@ QPDF::writeJSON(
std::string const& file_prefix,
std::set<std::string> wanted_objects)
{
+ int const depth_outer = 1;
+ int const depth_top = 1;
+ int const depth_qpdf = 2;
+ int const depth_qpdf_inner = 3;
+
if (version != 2) {
throw std::runtime_error(
"QPDF::writeJSON: only version 2 is supported");
}
bool first = true;
if (complete) {
- JSON::writeDictionaryOpen(p, first, 0);
+ JSON::writeDictionaryOpen(p, first, depth_outer);
} else {
first = first_key;
}
- JSON::writeDictionaryKey(p, first, "qpdf-v2", 1);
+ JSON::writeDictionaryKey(p, first, "qpdf", depth_top);
bool first_qpdf = true;
- JSON::writeDictionaryOpen(p, first_qpdf, 2);
+ JSON::writeArrayOpen(p, first_qpdf, depth_top);
+ JSON::writeNext(p, first_qpdf, depth_qpdf);
+ bool first_qpdf_inner = true;
+ JSON::writeDictionaryOpen(p, first_qpdf_inner, depth_qpdf);
JSON::writeDictionaryItem(
- p, first_qpdf, "pdfversion", JSON::makeString(getPDFVersion()), 2);
+ p,
+ first_qpdf_inner,
+ "jsonversion",
+ JSON::makeInt(version),
+ depth_qpdf_inner);
+ JSON::writeDictionaryItem(
+ p,
+ first_qpdf_inner,
+ "pdfversion",
+ JSON::makeString(getPDFVersion()),
+ depth_qpdf_inner);
+ JSON::writeDictionaryItem(
+ p,
+ first_qpdf_inner,
+ "pushedinheritedpageresources",
+ JSON::makeBool(everPushedInheritedAttributesToPages()),
+ depth_qpdf_inner);
+ JSON::writeDictionaryItem(
+ p,
+ first_qpdf_inner,
+ "calledgetallpages",
+ JSON::makeBool(everCalledGetAllPages()),
+ depth_qpdf_inner);
JSON::writeDictionaryItem(
p,
- first_qpdf,
+ first_qpdf_inner,
"maxobjectid",
JSON::makeInt(QIntC::to_longlong(getObjectCount())),
- 2);
- JSON::writeDictionaryKey(p, first_qpdf, "objects", 2);
- bool first_object = true;
- JSON::writeDictionaryOpen(p, first_object, 2);
+ depth_qpdf_inner);
+ JSON::writeDictionaryClose(p, first_qpdf_inner, depth_qpdf);
+ JSON::writeNext(p, first_qpdf, depth_qpdf);
+ JSON::writeDictionaryOpen(p, first_qpdf_inner, depth_qpdf);
bool all_objects = wanted_objects.empty();
for (auto& obj: getAllObjects()) {
std::string key = "obj:" + obj.unparse();
@@ -803,23 +870,23 @@ QPDF::writeJSON(
writeJSONStream(
version,
p,
- first_object,
+ first_qpdf_inner,
key,
obj,
decode_level,
json_stream_data,
file_prefix);
} else {
- writeJSONObject(version, p, first_object, key, obj);
+ writeJSONObject(version, p, first_qpdf_inner, key, obj);
}
}
}
if (all_objects || wanted_objects.count("trailer")) {
auto trailer = getTrailer();
- writeJSONObject(version, p, first_object, "trailer", trailer);
+ writeJSONObject(version, p, first_qpdf_inner, "trailer", trailer);
}
- JSON::writeDictionaryClose(p, first_object, 2);
- JSON::writeDictionaryClose(p, first_qpdf, 1);
+ JSON::writeDictionaryClose(p, first_qpdf_inner, depth_qpdf);
+ JSON::writeArrayClose(p, first_qpdf, depth_top);
if (complete) {
JSON::writeDictionaryClose(p, first, 0);
*p << "\n";
diff --git a/manual/json.rst b/manual/json.rst
index 92a89b6b..0becd405 100644
--- a/manual/json.rst
+++ b/manual/json.rst
@@ -256,17 +256,34 @@ qpdf JSON Output
The format of the JSON written by qpdf's :qpdf:ref:`--json-output`
flag or the ``QPDF::writeJSON`` API call is a JSON object consisting
-of a single key: ``"qpdf-v2"``. Any other top-level keys are ignored.
-While unknown keys in other places are ignored for future
-compatibility, in this case, ignoring other top-level keys is an
-explicit decision to allow users to include other keys for their own
-use. No new top-level keys will be added in JSON version 2.
+of a single key: ``"qpdf"``. This may be the only key, or it may be
+embedded in the output of ``qpdf --json``. Unknown keys are ignored
+for future compatibility. It is guaranteed that qpdf will never add
+any keys whose names start with ``xdata``, so users are free to add
+their own metadata using keys whose names start with ``xdata`` without
+fear of clashing with a future version of qpdf.
-The ``"qpdf-v2"`` key points to a JSON object with the following keys:
+The ``"qpdf"`` key points to a two-element JSON array. The first element is
+a JSON object with the following keys:
+
+- ``"jsonversion"`` -- a number indicating the JSON version used for
+ writing. This will always be ``2``.
- ``"pdfversion"`` -- a string containing PDF version as indicated in
the PDF header (e.g. ``"1.7"``, ``"2.0"``)
+- ``pushedinheritedpageresources`` -- a boolean indicating whether
+ the library pushed inherited resources down to the page level.
+ Certain library calls cause this to happen, and qpdf needs to know
+ when reading a JSON file back in whether it should do this as it may
+ cause certain objects to be renumbered.
+
+- ``calledgetallpages`` -- a boolean indicating whether
+ ``getAllPages`` was called prior to writing the JSON output. This
+ method causes page tree repair to occur, which may renumber some
+ objects (in very rare cases of corrupted page trees), so qpdf needs
+ to know this information when reading a JSON file back in.
+
- ``"maxobjectid"`` -- a number indicating the object ID of the
highest numbered object in the file. This is provided to make it
easier for software that wants to add new objects to the file as you
@@ -280,8 +297,8 @@ The ``"qpdf-v2"`` key points to a JSON object with the following keys:
dangling references and says to treat them as nulls. This can happen
if objects are removed from a PDF file.)
-- ``"objects"`` -- the actual PDF objects as described in
- :ref:`json.objects`.
+The second element is a JSON object containing the actual PDF objects
+as described in :ref:`json.objects`.
Note that writing JSON output is done by ``QPDF``, not ``QPDFWriter``.
As such, none of the things ``QPDFWriter`` does apply. This includes
@@ -302,10 +319,15 @@ qpdf JSON format.
.. code-block:: json
{
- "qpdf-v2": {
- "pdfversion": "1.3",
- "maxobjectid": 5,
- "objects": {
+ "qpdf": [
+ {
+ "jsonversion": 2,
+ "pdfversion": "1.3",
+ "pushedinheritedpageresources": false,
+ "calledgetallpages": false,
+ "maxobjectid": 5,
+ },
+ {
"obj:1 0 R": {
"value": {
"/Pages": "2 0 R",
@@ -359,7 +381,7 @@ qpdf JSON format.
}
}
}
- }
+ ]
}
.. _json.input:
diff --git a/qpdf/qpdf.testcov b/qpdf/qpdf.testcov
index bc4c2128..bfd3585f 100644
--- a/qpdf/qpdf.testcov
+++ b/qpdf/qpdf.testcov
@@ -668,3 +668,7 @@ QPDF_json non-trivial null reserved 0
QPDF_json data and datafile 0
QPDF_json no stream data in update mode 0
QPDF_json updating existing stream 0
+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
diff --git a/qpdf/qtest/qpdf-json.test b/qpdf/qtest/qpdf-json.test
index 23edda2e..abd9fa49 100644
--- a/qpdf/qtest/qpdf-json.test
+++ b/qpdf/qtest/qpdf-json.test
@@ -18,6 +18,8 @@ my $n_tests = 0;
my @badfiles = (
'no-qpdf-object',
+ 'qpdf-not-array',
+ 'qpdf-array-too-long',
'no-pdf-version',
'top-level-scalar',
'bad-pdf-version1',
diff --git a/qpdf/qtest/qpdf/exp-large-json.json b/qpdf/qtest/qpdf/exp-large-json.json
index 92f8b4b0..012ab69c 100644
--- a/qpdf/qtest/qpdf/exp-large-json.json
+++ b/qpdf/qtest/qpdf/exp-large-json.json
@@ -1,8 +1,13 @@
{
- "qpdf-v2": {
- "pdfversion": "1.3",
- "maxobjectid": 604,
- "objects": {
+ "qpdf": [
+ {
+ "jsonversion": 2,
+ "pdfversion": "1.3",
+ "pushedinheritedpageresources": false,
+ "calledgetallpages": false,
+ "maxobjectid": 604
+ },
+ {
"obj:1 0 R": {
"value": {
"/Pages": "2 0 R",
@@ -8444,5 +8449,5 @@
}
}
}
- }
+ ]
}
diff --git a/qpdf/qtest/qpdf/json-bad-data-json-file-v2.out b/qpdf/qtest/qpdf/json-bad-data-json-file-v2.out
index 8b2c825b..d0386ed0 100644
--- a/qpdf/qtest/qpdf/json-bad-data-json-file-v2.out
+++ b/qpdf/qtest/qpdf/json-bad-data-json-file-v2.out
@@ -1,8 +1,13 @@
{
- "qpdf-v2": {
- "pdfversion": "1.3",
- "maxobjectid": 6,
- "objects": {
+ "qpdf": [
+ {
+ "jsonversion": 2,
+ "pdfversion": "1.3",
+ "pushedinheritedpageresources": false,
+ "calledgetallpages": false,
+ "maxobjectid": 6
+ },
+ {
"obj:1 0 R": {
"value": {
"/Pages": "2 0 R",
@@ -71,5 +76,5 @@
}
}
}
- }
+ ]
}
diff --git a/qpdf/qtest/qpdf/json-bad-data-json-inline-v2.out b/qpdf/qtest/qpdf/json-bad-data-json-inline-v2.out
index c90bbf07..72d73f0e 100644
--- a/qpdf/qtest/qpdf/json-bad-data-json-inline-v2.out
+++ b/qpdf/qtest/qpdf/json-bad-data-json-inline-v2.out
@@ -1,8 +1,13 @@
{
- "qpdf-v2": {
- "pdfversion": "1.3",
- "maxobjectid": 6,
- "objects": {
+ "qpdf": [
+ {
+ "jsonversion": 2,
+ "pdfversion": "1.3",
+ "pushedinheritedpageresources": false,
+ "calledgetallpages": false,
+ "maxobjectid": 6
+ },
+ {
"obj:1 0 R": {
"value": {
"/Pages": "2 0 R",
@@ -71,5 +76,5 @@
}
}
}
- }
+ ]
}
diff --git a/qpdf/qtest/qpdf/json-image-streams-all-file-v2.out b/qpdf/qtest/qpdf/json-image-streams-all-file-v2.out
index 78c5bef8..82f50faa 100644
--- a/qpdf/qtest/qpdf/json-image-streams-all-file-v2.out
+++ b/qpdf/qtest/qpdf/json-image-streams-all-file-v2.out
@@ -1,8 +1,13 @@
{
- "qpdf-v2": {
- "pdfversion": "1.3",
- "maxobjectid": 30,
- "objects": {
+ "qpdf": [
+ {
+ "jsonversion": 2,
+ "pdfversion": "1.3",
+ "pushedinheritedpageresources": false,
+ "calledgetallpages": false,
+ "maxobjectid": 30
+ },
+ {
"obj:12 0 R": {
"stream": {
"datafile": "auto-12",
@@ -36,5 +41,5 @@
}
}
}
- }
+ ]
}
diff --git a/qpdf/qtest/qpdf/json-image-streams-generalized-file-v2.out b/qpdf/qtest/qpdf/json-image-streams-generalized-file-v2.out
index 78bbdbb2..7b5fc55e 100644
--- a/qpdf/qtest/qpdf/json-image-streams-generalized-file-v2.out
+++ b/qpdf/qtest/qpdf/json-image-streams-generalized-file-v2.out
@@ -1,8 +1,13 @@
{
- "qpdf-v2": {
- "pdfversion": "1.3",
- "maxobjectid": 30,
- "objects": {
+ "qpdf": [
+ {
+ "jsonversion": 2,
+ "pdfversion": "1.3",
+ "pushedinheritedpageresources": false,
+ "calledgetallpages": false,
+ "maxobjectid": 30
+ },
+ {
"obj:12 0 R": {
"stream": {
"datafile": "auto-12",
@@ -38,5 +43,5 @@
}
}
}
- }
+ ]
}
diff --git a/qpdf/qtest/qpdf/json-image-streams-generalized-inline-v2.out b/qpdf/qtest/qpdf/json-image-streams-generalized-inline-v2.out
index 2830f033..6e3fe192 100644
--- a/qpdf/qtest/qpdf/json-image-streams-generalized-inline-v2.out
+++ b/qpdf/qtest/qpdf/json-image-streams-generalized-inline-v2.out
@@ -1,8 +1,13 @@
{
- "qpdf-v2": {
- "pdfversion": "1.3",
- "maxobjectid": 30,
- "objects": {
+ "qpdf": [
+ {
+ "jsonversion": 2,
+ "pdfversion": "1.3",
+ "pushedinheritedpageresources": false,
+ "calledgetallpages": false,
+ "maxobjectid": 30
+ },
+ {
"obj:1 0 R": {
"value": {
"/Pages": "2 0 R",
@@ -457,5 +462,5 @@
}
}
}
- }
+ ]
}
diff --git a/qpdf/qtest/qpdf/json-image-streams-none-file-v2.out b/qpdf/qtest/qpdf/json-image-streams-none-file-v2.out
index a3f3c3cc..9a9f3b88 100644
--- a/qpdf/qtest/qpdf/json-image-streams-none-file-v2.out
+++ b/qpdf/qtest/qpdf/json-image-streams-none-file-v2.out
@@ -1,8 +1,13 @@
{
- "qpdf-v2": {
- "pdfversion": "1.3",
- "maxobjectid": 30,
- "objects": {
+ "qpdf": [
+ {
+ "jsonversion": 2,
+ "pdfversion": "1.3",
+ "pushedinheritedpageresources": false,
+ "calledgetallpages": false,
+ "maxobjectid": 30
+ },
+ {
"obj:12 0 R": {
"stream": {
"datafile": "auto-12",
@@ -40,5 +45,5 @@
}
}
}
- }
+ ]
}
diff --git a/qpdf/qtest/qpdf/json-image-streams-none-inline-v2.out b/qpdf/qtest/qpdf/json-image-streams-none-inline-v2.out
index 518ae50a..3ec8671b 100644
--- a/qpdf/qtest/qpdf/json-image-streams-none-inline-v2.out
+++ b/qpdf/qtest/qpdf/json-image-streams-none-inline-v2.out
@@ -1,8 +1,13 @@
{
- "qpdf-v2": {
- "pdfversion": "1.3",
- "maxobjectid": 30,
- "objects": {
+ "qpdf": [
+ {
+ "jsonversion": 2,
+ "pdfversion": "1.3",
+ "pushedinheritedpageresources": false,
+ "calledgetallpages": false,
+ "maxobjectid": 30
+ },
+ {
"obj:1 0 R": {
"value": {
"/Pages": "2 0 R",
@@ -478,5 +483,5 @@
}
}
}
- }
+ ]
}
diff --git a/qpdf/qtest/qpdf/json-image-streams-specialized-file-v2.out b/qpdf/qtest/qpdf/json-image-streams-specialized-file-v2.out
index e09d040f..b2a8a2d5 100644
--- a/qpdf/qtest/qpdf/json-image-streams-specialized-file-v2.out
+++ b/qpdf/qtest/qpdf/json-image-streams-specialized-file-v2.out
@@ -1,8 +1,13 @@
{
- "qpdf-v2": {
- "pdfversion": "1.3",
- "maxobjectid": 30,
- "objects": {
+ "qpdf": [
+ {
+ "jsonversion": 2,
+ "pdfversion": "1.3",
+ "pushedinheritedpageresources": false,
+ "calledgetallpages": false,
+ "maxobjectid": 30
+ },
+ {
"obj:12 0 R": {
"stream": {
"datafile": "auto-12",
@@ -37,5 +42,5 @@
}
}
}
- }
+ ]
}
diff --git a/qpdf/qtest/qpdf/json-image-streams-specialized-inline-v2.out b/qpdf/qtest/qpdf/json-image-streams-specialized-inline-v2.out
index 5ee93e2d..8a35a3f4 100644
--- a/qpdf/qtest/qpdf/json-image-streams-specialized-inline-v2.out
+++ b/qpdf/qtest/qpdf/json-image-streams-specialized-inline-v2.out
@@ -1,8 +1,13 @@
{
- "qpdf-v2": {
- "pdfversion": "1.3",
- "maxobjectid": 30,
- "objects": {
+ "qpdf": [
+ {
+ "jsonversion": 2,
+ "pdfversion": "1.3",
+ "pushedinheritedpageresources": false,
+ "calledgetallpages": false,
+ "maxobjectid": 30
+ },
+ {
"obj:1 0 R": {
"value": {
"/Pages": "2 0 R",
@@ -454,5 +459,5 @@
}
}
}
- }
+ ]
}
diff --git a/qpdf/qtest/qpdf/manual-qpdf-json-out.json b/qpdf/qtest/qpdf/manual-qpdf-json-out.json
index 1ad4ddad..b8edda25 100644
--- a/qpdf/qtest/qpdf/manual-qpdf-json-out.json
+++ b/qpdf/qtest/qpdf/manual-qpdf-json-out.json
@@ -1,8 +1,13 @@
{
- "qpdf-v2": {
- "pdfversion": "2.0",
- "maxobjectid": 100,
- "objects": {
+ "qpdf": [
+ {
+ "jsonversion": 2,
+ "pdfversion": "2.0",
+ "pushedinheritedpageresources": false,
+ "calledgetallpages": false,
+ "maxobjectid": 100
+ },
+ {
"obj:1 0 R": {
"value": {
"/Pages": "2 0 R",
@@ -139,5 +144,5 @@
}
}
}
- }
+ ]
}
diff --git a/qpdf/qtest/qpdf/manual-qpdf-json-pdf.json b/qpdf/qtest/qpdf/manual-qpdf-json-pdf.json
index afbb696d..9b28f8cf 100644
--- a/qpdf/qtest/qpdf/manual-qpdf-json-pdf.json
+++ b/qpdf/qtest/qpdf/manual-qpdf-json-pdf.json
@@ -1,8 +1,13 @@
{
- "qpdf-v2": {
- "pdfversion": "2.0",
- "maxobjectid": 10,
- "objects": {
+ "qpdf": [
+ {
+ "jsonversion": 2,
+ "pdfversion": "2.0",
+ "pushedinheritedpageresources": false,
+ "calledgetallpages": false,
+ "maxobjectid": 10
+ },
+ {
"obj:1 0 R": {
"value": {
"/Pages": "3 0 R",
@@ -146,5 +151,5 @@
}
}
}
- }
+ ]
}
diff --git a/qpdf/qtest/qpdf/manual-qpdf-json.json b/qpdf/qtest/qpdf/manual-qpdf-json.json
index 3fc04621..b6c4916c 100644
--- a/qpdf/qtest/qpdf/manual-qpdf-json.json
+++ b/qpdf/qtest/qpdf/manual-qpdf-json.json
@@ -2,17 +2,20 @@
"comment": [
"We allow and ignore other top-level keys"
],
- "qpdf-v2": {
- "pdfversion": "2.0",
- "maybe-future-key": {
- "x": [
- "Lots of times we ignore things",
- "for forward-compatibility so we don't have",
- "to change the version number if we add stuff",
- "in the future"
- ]
+ "qpdf": [
+ {
+ "jsonversion": 2,
+ "pdfversion": "2.0",
+ "maybe-future-key": {
+ "x": [
+ "Lots of times we ignore things",
+ "for forward-compatibility so we don't have",
+ "to change the version number if we add stuff",
+ "in the future"
+ ]
+ }
},
- "objects": {
+ {
"obj:3 0 R": {
"value": {
"/Contents": "4 0 R",
@@ -141,5 +144,5 @@
}
}
}
- }
+ ]
}
diff --git a/qpdf/qtest/qpdf/minimal-json-file-2.out b/qpdf/qtest/qpdf/minimal-json-file-2.out
index 8114a26f..e8f98d54 100644
--- a/qpdf/qtest/qpdf/minimal-json-file-2.out
+++ b/qpdf/qtest/qpdf/minimal-json-file-2.out
@@ -1,8 +1,13 @@
{
- "qpdf-v2": {
- "pdfversion": "1.3",
- "maxobjectid": 6,
- "objects": {
+ "qpdf": [
+ {
+ "jsonversion": 2,
+ "pdfversion": "1.3",
+ "pushedinheritedpageresources": false,
+ "calledgetallpages": false,
+ "maxobjectid": 6
+ },
+ {
"obj:1 0 R": {
"value": {
"/Pages": "2 0 R",
@@ -65,5 +70,5 @@
}
}
}
- }
+ ]
}
diff --git a/qpdf/qtest/qpdf/minimal-json-file.out b/qpdf/qtest/qpdf/minimal-json-file.out
index 520ebe83..2c8ddb39 100644
--- a/qpdf/qtest/qpdf/minimal-json-file.out
+++ b/qpdf/qtest/qpdf/minimal-json-file.out
@@ -1,8 +1,13 @@
{
- "qpdf-v2": {
- "pdfversion": "1.3",
- "maxobjectid": 6,
- "objects": {
+ "qpdf": [
+ {
+ "jsonversion": 2,
+ "pdfversion": "1.3",
+ "pushedinheritedpageresources": false,
+ "calledgetallpages": false,
+ "maxobjectid": 6
+ },
+ {
"obj:1 0 R": {
"value": {
"/Pages": "2 0 R",
@@ -65,5 +70,5 @@
}
}
}
- }
+ ]
}
diff --git a/qpdf/qtest/qpdf/qjson-bad-data.json b/qpdf/qtest/qpdf/qjson-bad-data.json
index 9b8880d4..64ee8050 100644
--- a/qpdf/qtest/qpdf/qjson-bad-data.json
+++ b/qpdf/qtest/qpdf/qjson-bad-data.json
@@ -1,8 +1,11 @@
{
- "qpdf-v2": {
- "pdfversion": "1.3",
- "maxobjectid": 6,
- "objects": {
+ "qpdf": [
+ {
+ "jsonversion": 2,
+ "pdfversion": "1.3",
+ "maxobjectid": 6
+ },
+ {
"obj:1 0 R": {
"value": {
"/Pages": "2 0 R",
@@ -64,5 +67,5 @@
}
}
}
- }
+ ]
}
diff --git a/qpdf/qtest/qpdf/qjson-bad-datafile.json b/qpdf/qtest/qpdf/qjson-bad-datafile.json
index 025f700b..614ea08f 100644
--- a/qpdf/qtest/qpdf/qjson-bad-datafile.json
+++ b/qpdf/qtest/qpdf/qjson-bad-datafile.json
@@ -1,8 +1,11 @@
{
- "qpdf-v2": {
- "pdfversion": "1.3",
- "maxobjectid": 6,
- "objects": {
+ "qpdf": [
+ {
+ "jsonversion": 2,
+ "pdfversion": "1.3",
+ "maxobjectid": 6
+ },
+ {
"obj:1 0 R": {
"value": {
"/Pages": "2 0 R",
@@ -64,5 +67,5 @@
}
}
}
- }
+ ]
}
diff --git a/qpdf/qtest/qpdf/qjson-bad-object-key.json b/qpdf/qtest/qpdf/qjson-bad-object-key.json
index e8637891..1b74d28a 100644
--- a/qpdf/qtest/qpdf/qjson-bad-object-key.json
+++ b/qpdf/qtest/qpdf/qjson-bad-object-key.json
@@ -1,8 +1,11 @@
{
- "qpdf-v2": {
- "pdfversion": "1.3",
- "maxobjectid": 6,
- "objects": {
+ "qpdf": [
+ {
+ "jsonversion": 2,
+ "pdfversion": "1.3",
+ "maxobjectid": 6
+ },
+ {
"potato": {
},
"obj:1 0 R": {
@@ -66,5 +69,5 @@
}
}
}
- }
+ ]
}
diff --git a/qpdf/qtest/qpdf/qjson-bad-object-key.out b/qpdf/qtest/qpdf/qjson-bad-object-key.out
index dee225f7..bf339090 100644
--- a/qpdf/qtest/qpdf/qjson-bad-object-key.out
+++ b/qpdf/qtest/qpdf/qjson-bad-object-key.out
@@ -1,2 +1,2 @@
-WARNING: qjson-bad-object-key.json (offset 97): object key should be "trailer" or "obj:n n R"
+WARNING: qjson-bad-object-key.json (offset 123): object key should be "trailer" or "obj:n n R"
qpdf: qjson-bad-object-key.json: errors found in JSON
diff --git a/qpdf/qtest/qpdf/qjson-bad-pdf-version1.json b/qpdf/qtest/qpdf/qjson-bad-pdf-version1.json
index e99c26ef..d4c5448c 100644
--- a/qpdf/qtest/qpdf/qjson-bad-pdf-version1.json
+++ b/qpdf/qtest/qpdf/qjson-bad-pdf-version1.json
@@ -1,8 +1,11 @@
{
- "qpdf-v2": {
- "pdfversion": "potato",
- "maxobjectid": 6,
- "objects": {
+ "qpdf": [
+ {
+ "jsonversion": "quack",
+ "pdfversion": "potato",
+ "maxobjectid": 6
+ },
+ {
"obj:1 0 R": {
"value": {
"/Pages": "2 0 R",
@@ -64,5 +67,5 @@
}
}
}
- }
+ ]
}
diff --git a/qpdf/qtest/qpdf/qjson-bad-pdf-version1.out b/qpdf/qtest/qpdf/qjson-bad-pdf-version1.out
index 2f18da41..f364f1a6 100644
--- a/qpdf/qtest/qpdf/qjson-bad-pdf-version1.out
+++ b/qpdf/qtest/qpdf/qjson-bad-pdf-version1.out
@@ -1,2 +1,3 @@
-WARNING: qjson-bad-pdf-version1.json (offset 35): invalid PDF version (must be x.y)
+WARNING: qjson-bad-pdf-version1.json (offset 41): invalid JSON version (must be 2)
+WARNING: qjson-bad-pdf-version1.json (offset 70): invalid PDF version (must be x.y)
qpdf: qjson-bad-pdf-version1.json: errors found in JSON
diff --git a/qpdf/qtest/qpdf/qjson-bad-pdf-version2.json b/qpdf/qtest/qpdf/qjson-bad-pdf-version2.json
index acc1642a..f70cfb52 100644
--- a/qpdf/qtest/qpdf/qjson-bad-pdf-version2.json
+++ b/qpdf/qtest/qpdf/qjson-bad-pdf-version2.json
@@ -1,8 +1,11 @@
{
- "qpdf-v2": {
- "pdfversion": [],
- "maxobjectid": 6,
- "objects": {
+ "qpdf": [
+ {
+ "jsonversion": 850,
+ "pdfversion": [],
+ "maxobjectid": 6
+ },
+ {
"obj:1 0 R": {
"value": {
"/Pages": "2 0 R",
@@ -64,5 +67,5 @@
}
}
}
- }
+ ]
}
diff --git a/qpdf/qtest/qpdf/qjson-bad-pdf-version2.out b/qpdf/qtest/qpdf/qjson-bad-pdf-version2.out
index 3a5086ba..65be40ca 100644
--- a/qpdf/qtest/qpdf/qjson-bad-pdf-version2.out
+++ b/qpdf/qtest/qpdf/qjson-bad-pdf-version2.out
@@ -1,2 +1,3 @@
-WARNING: qjson-bad-pdf-version2.json (offset 35): invalid PDF version (must be x.y)
+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)
qpdf: qjson-bad-pdf-version2.json: errors found in JSON
diff --git a/qpdf/qtest/qpdf/qjson-missing-objects.json b/qpdf/qtest/qpdf/qjson-missing-objects.json
index ae287217..a5d6b485 100644
--- a/qpdf/qtest/qpdf/qjson-missing-objects.json
+++ b/qpdf/qtest/qpdf/qjson-missing-objects.json
@@ -1,6 +1,9 @@
{
- "qpdf-v2": {
- "pdfversion": "1.3",
- "maxobjectid": 6
- }
+ "qpdf": [
+ {
+ "jsonversion": 2,
+ "pdfversion": "1.3",
+ "maxobjectid": 6
+ }
+ ]
}
diff --git a/qpdf/qtest/qpdf/qjson-missing-objects.out b/qpdf/qtest/qpdf/qjson-missing-objects.out
index 2692a97b..e5de89df 100644
--- a/qpdf/qtest/qpdf/qjson-missing-objects.out
+++ b/qpdf/qtest/qpdf/qjson-missing-objects.out
@@ -1,2 +1,2 @@
-WARNING: qjson-missing-objects.json: "qpdf-v2.objects" was not seen
+WARNING: qjson-missing-objects.json: "qpdf[1]" was not seen
qpdf: qjson-missing-objects.json: errors found in JSON
diff --git a/qpdf/qtest/qpdf/qjson-missing-trailer.json b/qpdf/qtest/qpdf/qjson-missing-trailer.json
index 21050e05..e2fe9a10 100644
--- a/qpdf/qtest/qpdf/qjson-missing-trailer.json
+++ b/qpdf/qtest/qpdf/qjson-missing-trailer.json
@@ -1,8 +1,11 @@
{
- "qpdf-v2": {
- "pdfversion": "1.3",
- "maxobjectid": 6,
- "objects": {
+ "qpdf": [
+ {
+ "jsonversion": 2,
+ "pdfversion": "1.3",
+ "maxobjectid": 6
+ },
+ {
"obj:1 0 R": {
"value": {
"/Pages": "2 0 R",
@@ -58,5 +61,5 @@
}
}
}
- }
+ ]
}
diff --git a/qpdf/qtest/qpdf/qjson-missing-trailer.out b/qpdf/qtest/qpdf/qjson-missing-trailer.out
index 3a4b7910..de3793dd 100644
--- a/qpdf/qtest/qpdf/qjson-missing-trailer.out
+++ b/qpdf/qtest/qpdf/qjson-missing-trailer.out
@@ -1,2 +1,2 @@
-WARNING: qjson-missing-trailer.json: "qpdf-v2.objects.trailer" was not seen
+WARNING: qjson-missing-trailer.json: "qpdf[1].trailer" was not seen
qpdf: qjson-missing-trailer.json: errors found in JSON
diff --git a/qpdf/qtest/qpdf/qjson-no-pdf-version.json b/qpdf/qtest/qpdf/qjson-no-pdf-version.json
index 77bfe1ca..53c5a725 100644
--- a/qpdf/qtest/qpdf/qjson-no-pdf-version.json
+++ b/qpdf/qtest/qpdf/qjson-no-pdf-version.json
@@ -1,7 +1,9 @@
{
- "qpdf-v2": {
- "maxobjectid": 6,
- "objects": {
+ "qpdf": [
+ {
+ "maxobjectid": 6
+ },
+ {
"obj:1 0 R": {
"value": {
"/Pages": "2 0 R",
@@ -63,5 +65,5 @@
}
}
}
- }
+ ]
}
diff --git a/qpdf/qtest/qpdf/qjson-no-pdf-version.out b/qpdf/qtest/qpdf/qjson-no-pdf-version.out
index 6a00d76c..a57ffb18 100644
--- a/qpdf/qtest/qpdf/qjson-no-pdf-version.out
+++ b/qpdf/qtest/qpdf/qjson-no-pdf-version.out
@@ -1,2 +1,3 @@
-WARNING: qjson-no-pdf-version.json: "qpdf-v2.pdfversion" was not seen
+WARNING: qjson-no-pdf-version.json: "qpdf[0].jsonversion" was not seen
+WARNING: qjson-no-pdf-version.json: "qpdf[0].pdfversion" was not seen
qpdf: qjson-no-pdf-version.json: errors found in JSON
diff --git a/qpdf/qtest/qpdf/qjson-obj-key-errors.json b/qpdf/qtest/qpdf/qjson-obj-key-errors.json
index 2adc33d4..627421c8 100644
--- a/qpdf/qtest/qpdf/qjson-obj-key-errors.json
+++ b/qpdf/qtest/qpdf/qjson-obj-key-errors.json
@@ -1,8 +1,11 @@
{
- "qpdf-v2": {
- "pdfversion": "1.3",
- "maxobjectid": 6,
- "objects": {
+ "qpdf": [
+ {
+ "jsonversion": 2,
+ "pdfversion": "1.3",
+ "maxobjectid": 6
+ },
+ {
"obj:1 0 R": {
"value": {
"/Pages": "2 0 R",
@@ -55,5 +58,5 @@
}
}
}
- }
+ ]
}
diff --git a/qpdf/qtest/qpdf/qjson-obj-key-errors.out b/qpdf/qtest/qpdf/qjson-obj-key-errors.out
index e739a2f8..0263f294 100644
--- a/qpdf/qtest/qpdf/qjson-obj-key-errors.out
+++ b/qpdf/qtest/qpdf/qjson-obj-key-errors.out
@@ -1,7 +1,7 @@
-WARNING: qjson-obj-key-errors.json (obj:2 0 R, offset 218): object must have exactly one of "value" or "stream"
-WARNING: qjson-obj-key-errors.json (obj:3 0 R, offset 516): object must have exactly one of "value" or "stream"
-WARNING: qjson-obj-key-errors.json (obj:4 0 R, offset 684): "stream" is missing "dict"
-WARNING: qjson-obj-key-errors.json (obj:4 0 R, offset 684): new "stream" must have exactly one of "data" or "datafile"
-WARNING: qjson-obj-key-errors.json (obj:5 0 R, offset 774): new "stream" must have exactly one of "data" or "datafile"
-WARNING: qjson-obj-key-errors.json (trailer, offset 1152): "trailer" is missing "value"
+WARNING: qjson-obj-key-errors.json (obj:2 0 R, offset 244): object must have exactly one of "value" or "stream"
+WARNING: qjson-obj-key-errors.json (obj:3 0 R, offset 542): object must have exactly one of "value" or "stream"
+WARNING: qjson-obj-key-errors.json (obj:4 0 R, offset 710): "stream" is missing "dict"
+WARNING: qjson-obj-key-errors.json (obj:4 0 R, offset 710): new "stream" must have exactly one of "data" or "datafile"
+WARNING: qjson-obj-key-errors.json (obj:5 0 R, offset 800): new "stream" must have exactly one of "data" or "datafile"
+WARNING: qjson-obj-key-errors.json (trailer, offset 1178): "trailer" is missing "value"
qpdf: qjson-obj-key-errors.json: errors found in JSON
diff --git a/qpdf/qtest/qpdf/qjson-object-not-dict.json b/qpdf/qtest/qpdf/qjson-object-not-dict.json
index 93357afd..c7f3abc7 100644
--- a/qpdf/qtest/qpdf/qjson-object-not-dict.json
+++ b/qpdf/qtest/qpdf/qjson-object-not-dict.json
@@ -1,8 +1,11 @@
{
- "qpdf-v2": {
- "pdfversion": "1.3",
- "maxobjectid": 6,
- "objects": {
+ "qpdf": [
+ {
+ "jsonversion": 2,
+ "pdfversion": "1.3",
+ "maxobjectid": 6
+ },
+ {
"obj:1 0 R": "potato",
"obj:2 0 R": {
"value": {
@@ -59,5 +62,5 @@
}
}
}
- }
+ ]
}
diff --git a/qpdf/qtest/qpdf/qjson-object-not-dict.out b/qpdf/qtest/qpdf/qjson-object-not-dict.out
index 1268c83d..5c77c88b 100644
--- a/qpdf/qtest/qpdf/qjson-object-not-dict.out
+++ b/qpdf/qtest/qpdf/qjson-object-not-dict.out
@@ -1,2 +1,2 @@
-WARNING: qjson-object-not-dict.json (obj:1 0 R, offset 100): "obj:1 0 R" must be a dictionary
+WARNING: qjson-object-not-dict.json (obj:1 0 R, offset 126): "obj:1 0 R" must be a dictionary
qpdf: qjson-object-not-dict.json: errors found in JSON
diff --git a/qpdf/qtest/qpdf/qjson-objects-not-dict.json b/qpdf/qtest/qpdf/qjson-objects-not-dict.json
index 12870f81..55288a37 100644
--- a/qpdf/qtest/qpdf/qjson-objects-not-dict.json
+++ b/qpdf/qtest/qpdf/qjson-objects-not-dict.json
@@ -1,6 +1,9 @@
{
- "qpdf-v2": {
- "pdfversion": "1.7",
- "objects": false
- }
+ "qpdf": [
+ {
+ "jsonversion": 2,
+ "pdfversion": "1.7"
+ },
+ false
+ ]
}
diff --git a/qpdf/qtest/qpdf/qjson-objects-not-dict.out b/qpdf/qtest/qpdf/qjson-objects-not-dict.out
index b009ef63..219b00e2 100644
--- a/qpdf/qtest/qpdf/qjson-objects-not-dict.out
+++ b/qpdf/qtest/qpdf/qjson-objects-not-dict.out
@@ -1,3 +1,3 @@
-WARNING: qjson-objects-not-dict.json (offset 58): "objects" must be a dictionary
-WARNING: qjson-objects-not-dict.json: "qpdf-v2.objects.trailer" was not seen
+WARNING: qjson-objects-not-dict.json (offset 82): "qpdf[1]" must be a dictionary
+WARNING: qjson-objects-not-dict.json: "qpdf[1].trailer" was not seen
qpdf: qjson-objects-not-dict.json: errors found in JSON
diff --git a/qpdf/qtest/qpdf/qjson-qpdf-array-too-long.json b/qpdf/qtest/qpdf/qjson-qpdf-array-too-long.json
new file mode 100644
index 00000000..ed05b142
--- /dev/null
+++ b/qpdf/qtest/qpdf/qjson-qpdf-array-too-long.json
@@ -0,0 +1,72 @@
+{
+ "qpdf": [
+ {
+ "jsonversion": 2,
+ "pdfversion": "1.3",
+ "maxobjectid": 6
+ },
+ {
+ "obj:1 0 R": {
+ "value": {
+ "/Pages": "2 0 R",
+ "/Type": "/Catalog"
+ }
+ },
+ "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
+ }
+ }
+ },
+ "this doesn't belong here"
+ ]
+}
diff --git a/qpdf/qtest/qpdf/qjson-qpdf-array-too-long.out b/qpdf/qtest/qpdf/qjson-qpdf-array-too-long.out
new file mode 100644
index 00000000..065286d6
--- /dev/null
+++ b/qpdf/qtest/qpdf/qjson-qpdf-array-too-long.out
@@ -0,0 +1,2 @@
+WARNING: qjson-qpdf-array-too-long.json (offset 1348): "qpdf" must have two elements
+qpdf: qjson-qpdf-array-too-long.json: errors found in JSON
diff --git a/qpdf/qtest/qpdf/qjson-qpdf-not-array.json b/qpdf/qtest/qpdf/qjson-qpdf-not-array.json
new file mode 100644
index 00000000..68846aeb
--- /dev/null
+++ b/qpdf/qtest/qpdf/qjson-qpdf-not-array.json
@@ -0,0 +1,5 @@
+{
+ "qpdf": {
+ "potato": "salad"
+ }
+}
diff --git a/qpdf/qtest/qpdf/qjson-qpdf-not-array.out b/qpdf/qtest/qpdf/qjson-qpdf-not-array.out
new file mode 100644
index 00000000..3122ba78
--- /dev/null
+++ b/qpdf/qtest/qpdf/qjson-qpdf-not-array.out
@@ -0,0 +1,5 @@
+WARNING: qjson-qpdf-not-array.json (offset 12): "qpdf" must be an array
+WARNING: qjson-qpdf-not-array.json: "qpdf[0].jsonversion" was not seen
+WARNING: qjson-qpdf-not-array.json: "qpdf[0].pdfversion" was not seen
+WARNING: qjson-qpdf-not-array.json: "qpdf[1]" was not seen
+qpdf: qjson-qpdf-not-array.json: errors found in JSON
diff --git a/qpdf/qtest/qpdf/qjson-stream-dict-not-dict.json b/qpdf/qtest/qpdf/qjson-stream-dict-not-dict.json
index a34e1a7e..7f68f756 100644
--- a/qpdf/qtest/qpdf/qjson-stream-dict-not-dict.json
+++ b/qpdf/qtest/qpdf/qjson-stream-dict-not-dict.json
@@ -1,12 +1,15 @@
{
- "qpdf-v2": {
- "pdfversion": "1.7",
- "objects": {
+ "qpdf": [
+ {
+ "jsonversion": 2,
+ "pdfversion": "1.7"
+ },
+ {
"obj:1 0 R": {
"stream": {
"dict": "quack"
}
}
}
- }
+ ]
}
diff --git a/qpdf/qtest/qpdf/qjson-stream-dict-not-dict.out b/qpdf/qtest/qpdf/qjson-stream-dict-not-dict.out
index 39b5207d..a264839f 100644
--- a/qpdf/qtest/qpdf/qjson-stream-dict-not-dict.out
+++ b/qpdf/qtest/qpdf/qjson-stream-dict-not-dict.out
@@ -1,5 +1,5 @@
-WARNING: qjson-stream-dict-not-dict.json (obj:1 0 R, offset 118): "stream.dict" must be a dictionary
-WARNING: qjson-stream-dict-not-dict.json (obj:1 0 R, offset 118): unrecognized string value
-WARNING: qjson-stream-dict-not-dict.json (obj:1 0 R, offset 98): new "stream" must have exactly one of "data" or "datafile"
-WARNING: qjson-stream-dict-not-dict.json: "qpdf-v2.objects.trailer" was not seen
+WARNING: qjson-stream-dict-not-dict.json (obj:1 0 R, offset 142): "stream.dict" must be a dictionary
+WARNING: qjson-stream-dict-not-dict.json (obj:1 0 R, offset 142): unrecognized string value
+WARNING: qjson-stream-dict-not-dict.json (obj:1 0 R, offset 122): new "stream" must have exactly one of "data" or "datafile"
+WARNING: qjson-stream-dict-not-dict.json: "qpdf[1].trailer" was not seen
qpdf: qjson-stream-dict-not-dict.json: errors found in JSON
diff --git a/qpdf/qtest/qpdf/qjson-stream-not-dict.json b/qpdf/qtest/qpdf/qjson-stream-not-dict.json
index fedf657f..d6d368e6 100644
--- a/qpdf/qtest/qpdf/qjson-stream-not-dict.json
+++ b/qpdf/qtest/qpdf/qjson-stream-not-dict.json
@@ -1,10 +1,13 @@
{
- "qpdf-v2": {
- "pdfversion": "1.7",
- "objects": {
+ "qpdf": [
+ {
+ "jsonversion": 2,
+ "pdfversion": "1.7"
+ },
+ {
"obj:1 0 R": {
"stream": 3
}
}
- }
+ ]
}
diff --git a/qpdf/qtest/qpdf/qjson-stream-not-dict.out b/qpdf/qtest/qpdf/qjson-stream-not-dict.out
index 4d492bcf..6a462ff6 100644
--- a/qpdf/qtest/qpdf/qjson-stream-not-dict.out
+++ b/qpdf/qtest/qpdf/qjson-stream-not-dict.out
@@ -1,3 +1,3 @@
-WARNING: qjson-stream-not-dict.json (obj:1 0 R, offset 99): "stream" must be a dictionary
-WARNING: qjson-stream-not-dict.json: "qpdf-v2.objects.trailer" was not seen
+WARNING: qjson-stream-not-dict.json (obj:1 0 R, offset 123): "stream" must be a dictionary
+WARNING: qjson-stream-not-dict.json: "qpdf[1].trailer" was not seen
qpdf: qjson-stream-not-dict.json: errors found in JSON
diff --git a/qpdf/qtest/qpdf/qjson-trailer-not-dict.json b/qpdf/qtest/qpdf/qjson-trailer-not-dict.json
index 0617095e..ee2b1b9f 100644
--- a/qpdf/qtest/qpdf/qjson-trailer-not-dict.json
+++ b/qpdf/qtest/qpdf/qjson-trailer-not-dict.json
@@ -1,8 +1,11 @@
{
- "qpdf-v2": {
- "pdfversion": "1.3",
- "maxobjectid": 6,
- "objects": {
+ "qpdf": [
+ {
+ "jsonversion": 2,
+ "pdfversion": "1.3",
+ "maxobjectid": 6
+ },
+ {
"obj:1 0 R": {
"value": {
"/Pages": "2 0 R",
@@ -61,5 +64,5 @@
"value": false
}
}
- }
+ ]
}
diff --git a/qpdf/qtest/qpdf/qjson-trailer-not-dict.out b/qpdf/qtest/qpdf/qjson-trailer-not-dict.out
index 5a7ce0e8..3b9d482d 100644
--- a/qpdf/qtest/qpdf/qjson-trailer-not-dict.out
+++ b/qpdf/qtest/qpdf/qjson-trailer-not-dict.out
@@ -1,2 +1,2 @@
-WARNING: qjson-trailer-not-dict.json (trailer, offset 1243): "trailer.value" must be a dictionary
+WARNING: qjson-trailer-not-dict.json (trailer, offset 1269): "trailer.value" must be a dictionary
qpdf: qjson-trailer-not-dict.json: errors found in JSON
diff --git a/qpdf/qtest/qpdf/qjson-trailer-stream.json b/qpdf/qtest/qpdf/qjson-trailer-stream.json
index 2b991a74..3e3a8545 100644
--- a/qpdf/qtest/qpdf/qjson-trailer-stream.json
+++ b/qpdf/qtest/qpdf/qjson-trailer-stream.json
@@ -1,8 +1,11 @@
{
- "qpdf-v2": {
- "pdfversion": "1.3",
- "maxobjectid": 6,
- "objects": {
+ "qpdf": [
+ {
+ "jsonversion": 2,
+ "pdfversion": "1.3",
+ "maxobjectid": 6
+ },
+ {
"obj:1 0 R": {
"value": {
"/Pages": "2 0 R",
@@ -61,5 +64,5 @@
"stream": {}
}
}
- }
+ ]
}
diff --git a/qpdf/qtest/qpdf/qjson-trailer-stream.out b/qpdf/qtest/qpdf/qjson-trailer-stream.out
index 94a60873..a625cd6d 100644
--- a/qpdf/qtest/qpdf/qjson-trailer-stream.out
+++ b/qpdf/qtest/qpdf/qjson-trailer-stream.out
@@ -1,2 +1,2 @@
-WARNING: qjson-trailer-stream.json (trailer, offset 1243): the trailer may not be a stream
+WARNING: qjson-trailer-stream.json (trailer, offset 1269): the trailer may not be a stream
qpdf: qjson-trailer-stream.json: errors found in JSON
diff --git a/qpdf/qtest/qpdf/qpdf-json-update-errors.json b/qpdf/qtest/qpdf/qpdf-json-update-errors.json
index 4f699342..4666856d 100644
--- a/qpdf/qtest/qpdf/qpdf-json-update-errors.json
+++ b/qpdf/qtest/qpdf/qpdf-json-update-errors.json
@@ -1,6 +1,9 @@
{
- "qpdf-v2": {
- "objects": {
+ "qpdf": [
+ {
+ "jsonversion": 2
+ },
+ {
"obj:4 0 R": {
"stream": {
"data": "QlQKICAvRjEgMjQgVGYKICA3MiA3MjAgVGQKICAoUG90YXRvKSBUagpFVAo=",
@@ -16,5 +19,5 @@
}
}
}
- }
+ ]
}
diff --git a/qpdf/qtest/qpdf/replace-with-stream.json b/qpdf/qtest/qpdf/replace-with-stream.json
index 7004c2a1..0c824707 100644
--- a/qpdf/qtest/qpdf/replace-with-stream.json
+++ b/qpdf/qtest/qpdf/replace-with-stream.json
@@ -1,8 +1,11 @@
{
- "qpdf-v2": {
- "pdfversion": "2.0",
- "maxobjectid": 9,
- "objects": {
+ "qpdf": [
+ {
+ "jsonversion": 2,
+ "pdfversion": "2.0",
+ "maxobjectid": 9
+ },
+ {
"obj:8 0 R": {
"stream": {
"data": "bmV3LXN0cmVhbS1oZXJlCg==",
@@ -12,5 +15,5 @@
}
}
}
- }
+ ]
}
diff --git a/qpdf/qtest/qpdf/test-89.out b/qpdf/qtest/qpdf/test-89.out
index 97d71e1b..417465aa 100644
--- a/qpdf/qtest/qpdf/test-89.out
+++ b/qpdf/qtest/qpdf/test-89.out
@@ -1,5 +1,5 @@
-WARNING: manual-qpdf-json.json, trailer at offset 1761: operation for array attempted on object of type dictionary: ignoring attempt to append item
-WARNING: manual-qpdf-json.json, obj:1 0 R at offset 1079: operation for array attempted on object of type dictionary: ignoring attempt to append item
-WARNING: manual-qpdf-json.json, obj:5 0 R at offset 1404: operation for dictionary attempted on object of type array: ignoring key replacement request
-WARNING: manual-qpdf-json.json, obj:5 0 R at offset 1416: operation for dictionary attempted on object of type name: ignoring key replacement request
+WARNING: manual-qpdf-json.json, trailer at offset 1801: operation for array attempted on object of type dictionary: ignoring attempt to append item
+WARNING: manual-qpdf-json.json, obj:1 0 R at offset 1119: operation for array attempted on object of type dictionary: ignoring attempt to append item
+WARNING: manual-qpdf-json.json, obj:5 0 R at offset 1444: operation for dictionary attempted on object of type array: ignoring key replacement request
+WARNING: manual-qpdf-json.json, obj:5 0 R at offset 1456: operation for dictionary attempted on object of type name: ignoring key replacement request
test 89 done
diff --git a/qpdf/qtest/qpdf/test-90.out b/qpdf/qtest/qpdf/test-90.out
index 2c535a09..743bff92 100644
--- a/qpdf/qtest/qpdf/test-90.out
+++ b/qpdf/qtest/qpdf/test-90.out
@@ -1,5 +1,5 @@
-WARNING: various-updates.json, trailer at offset 580: operation for array attempted on object of type dictionary: ignoring attempt to append item
-WARNING: various-updates.json, obj:7 0 R at offset 171: operation for array attempted on object of type dictionary: ignoring attempt to append item
-WARNING: various-updates.json, obj:7 0 R at offset 283: operation for integer attempted on object of type array: returning 0
+WARNING: various-updates.json, trailer at offset 606: operation for array attempted on object of type dictionary: ignoring attempt to append item
+WARNING: various-updates.json, obj:7 0 R at offset 197: operation for array attempted on object of type dictionary: ignoring attempt to append item
+WARNING: various-updates.json, obj:7 0 R at offset 309: operation for integer attempted on object of type array: returning 0
WARNING: good13.pdf, object 1 0 at offset 19: operation for array attempted on object of type dictionary: ignoring attempt to append item
test 90 done
diff --git a/qpdf/qtest/qpdf/update-from-json-errors.out b/qpdf/qtest/qpdf/update-from-json-errors.out
index 763579c3..530d707d 100644
--- a/qpdf/qtest/qpdf/update-from-json-errors.out
+++ b/qpdf/qtest/qpdf/update-from-json-errors.out
@@ -1,4 +1,4 @@
-WARNING: good13.pdf (obj:4 0 R from qpdf-json-update-errors.json, offset 73): existing "stream" may at most one of "data" or "datafile"
-WARNING: good13.pdf (obj:20 0 R from qpdf-json-update-errors.json, offset 313): unrecognized string value
-WARNING: good13.pdf (obj:20 0 R from qpdf-json-update-errors.json, offset 271): new "stream" must have exactly one of "data" or "datafile"
+WARNING: good13.pdf (obj:4 0 R from qpdf-json-update-errors.json, offset 95): existing "stream" may at most one of "data" or "datafile"
+WARNING: good13.pdf (obj:20 0 R from qpdf-json-update-errors.json, offset 335): unrecognized string value
+WARNING: good13.pdf (obj:20 0 R from qpdf-json-update-errors.json, offset 293): new "stream" must have exactly one of "data" or "datafile"
qpdf: qpdf-json-update-errors.json: errors found in JSON
diff --git a/qpdf/qtest/qpdf/update-stream-data.json b/qpdf/qtest/qpdf/update-stream-data.json
index a650e93f..ef899269 100644
--- a/qpdf/qtest/qpdf/update-stream-data.json
+++ b/qpdf/qtest/qpdf/update-stream-data.json
@@ -1,8 +1,11 @@
{
- "qpdf-v2": {
- "pdfversion": "2.0",
- "maxobjectid": 9,
- "objects": {
+ "qpdf": [
+ {
+ "jsonversion": 2,
+ "pdfversion": "2.0",
+ "maxobjectid": 9
+ },
+ {
"obj:1 0 R": {
"value": {
"/Pages": "2 0 R",
@@ -16,5 +19,5 @@
}
}
}
- }
+ ]
}
diff --git a/qpdf/qtest/qpdf/update-stream-dict-only.json b/qpdf/qtest/qpdf/update-stream-dict-only.json
index bc0a17ce..93ec4af1 100644
--- a/qpdf/qtest/qpdf/update-stream-dict-only.json
+++ b/qpdf/qtest/qpdf/update-stream-dict-only.json
@@ -1,8 +1,11 @@
{
- "qpdf-v2": {
- "pdfversion": "2.0",
- "maxobjectid": 9,
- "objects": {
+ "qpdf": [
+ {
+ "jsonversion": 2,
+ "pdfversion": "2.0",
+ "maxobjectid": 9
+ },
+ {
"obj:4 0 R": {
"stream": {
"dict": {
@@ -11,5 +14,5 @@
}
}
}
- }
+ ]
}
diff --git a/qpdf/qtest/qpdf/various-updates.json b/qpdf/qtest/qpdf/various-updates.json
index 80e36465..883eae8c 100644
--- a/qpdf/qtest/qpdf/various-updates.json
+++ b/qpdf/qtest/qpdf/various-updates.json
@@ -1,8 +1,11 @@
{
- "qpdf-v2": {
- "pdfversion": "2.0",
- "maxobjectid": 9,
- "objects": {
+ "qpdf": [
+ {
+ "jsonversion": 2,
+ "pdfversion": "2.0",
+ "maxobjectid": 9
+ },
+ {
"obj:5 0 R": {
"value": null
},
@@ -35,5 +38,5 @@
}
}
}
- }
+ ]
}