From d01c4f8819ea93797784c19ecdd623eb41f2a8b4 Mon Sep 17 00:00:00 2001 From: Jay Berkenbilt Date: Sat, 30 Jul 2022 19:29:55 -0400 Subject: [PATCH] Change --json-output format --- TODO | 6 ++---- cSpell.json | 2 ++ include/qpdf/QPDF.hh | 3 +++ libqpdf/QPDFJob.cc | 3 +++ libqpdf/QPDF_json.cc | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------- manual/json.rst | 48 +++++++++++++++++++++++++++++++++++------------- qpdf/qpdf.testcov | 4 ++++ qpdf/qtest/qpdf-json.test | 2 ++ qpdf/qtest/qpdf/exp-large-json.json | 15 ++++++++++----- qpdf/qtest/qpdf/json-bad-data-json-file-v2.out | 15 ++++++++++----- qpdf/qtest/qpdf/json-bad-data-json-inline-v2.out | 15 ++++++++++----- qpdf/qtest/qpdf/json-image-streams-all-file-v2.out | 15 ++++++++++----- qpdf/qtest/qpdf/json-image-streams-generalized-file-v2.out | 15 ++++++++++----- qpdf/qtest/qpdf/json-image-streams-generalized-inline-v2.out | 15 ++++++++++----- qpdf/qtest/qpdf/json-image-streams-none-file-v2.out | 15 ++++++++++----- qpdf/qtest/qpdf/json-image-streams-none-inline-v2.out | 15 ++++++++++----- qpdf/qtest/qpdf/json-image-streams-specialized-file-v2.out | 15 ++++++++++----- qpdf/qtest/qpdf/json-image-streams-specialized-inline-v2.out | 15 ++++++++++----- qpdf/qtest/qpdf/manual-qpdf-json-out.json | 15 ++++++++++----- qpdf/qtest/qpdf/manual-qpdf-json-pdf.json | 15 ++++++++++----- qpdf/qtest/qpdf/manual-qpdf-json.json | 25 ++++++++++++++----------- qpdf/qtest/qpdf/minimal-json-file-2.out | 15 ++++++++++----- qpdf/qtest/qpdf/minimal-json-file.out | 15 ++++++++++----- qpdf/qtest/qpdf/qjson-bad-data.json | 13 ++++++++----- qpdf/qtest/qpdf/qjson-bad-datafile.json | 13 ++++++++----- qpdf/qtest/qpdf/qjson-bad-object-key.json | 13 ++++++++----- qpdf/qtest/qpdf/qjson-bad-object-key.out | 2 +- qpdf/qtest/qpdf/qjson-bad-pdf-version1.json | 13 ++++++++----- qpdf/qtest/qpdf/qjson-bad-pdf-version1.out | 3 ++- qpdf/qtest/qpdf/qjson-bad-pdf-version2.json | 13 ++++++++----- qpdf/qtest/qpdf/qjson-bad-pdf-version2.out | 3 ++- qpdf/qtest/qpdf/qjson-missing-objects.json | 11 +++++++---- qpdf/qtest/qpdf/qjson-missing-objects.out | 2 +- qpdf/qtest/qpdf/qjson-missing-trailer.json | 13 ++++++++----- qpdf/qtest/qpdf/qjson-missing-trailer.out | 2 +- qpdf/qtest/qpdf/qjson-no-pdf-version.json | 10 ++++++---- qpdf/qtest/qpdf/qjson-no-pdf-version.out | 3 ++- qpdf/qtest/qpdf/qjson-obj-key-errors.json | 13 ++++++++----- qpdf/qtest/qpdf/qjson-obj-key-errors.out | 12 ++++++------ qpdf/qtest/qpdf/qjson-object-not-dict.json | 13 ++++++++----- qpdf/qtest/qpdf/qjson-object-not-dict.out | 2 +- qpdf/qtest/qpdf/qjson-objects-not-dict.json | 11 +++++++---- qpdf/qtest/qpdf/qjson-objects-not-dict.out | 4 ++-- qpdf/qtest/qpdf/qjson-qpdf-array-too-long.json | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ qpdf/qtest/qpdf/qjson-qpdf-array-too-long.out | 2 ++ qpdf/qtest/qpdf/qjson-qpdf-not-array.json | 5 +++++ qpdf/qtest/qpdf/qjson-qpdf-not-array.out | 5 +++++ qpdf/qtest/qpdf/qjson-stream-dict-not-dict.json | 11 +++++++---- qpdf/qtest/qpdf/qjson-stream-dict-not-dict.out | 8 ++++---- qpdf/qtest/qpdf/qjson-stream-not-dict.json | 11 +++++++---- qpdf/qtest/qpdf/qjson-stream-not-dict.out | 4 ++-- qpdf/qtest/qpdf/qjson-trailer-not-dict.json | 13 ++++++++----- qpdf/qtest/qpdf/qjson-trailer-not-dict.out | 2 +- qpdf/qtest/qpdf/qjson-trailer-stream.json | 13 ++++++++----- qpdf/qtest/qpdf/qjson-trailer-stream.out | 2 +- qpdf/qtest/qpdf/qpdf-json-update-errors.json | 9 ++++++--- qpdf/qtest/qpdf/replace-with-stream.json | 13 ++++++++----- qpdf/qtest/qpdf/test-89.out | 8 ++++---- qpdf/qtest/qpdf/test-90.out | 6 +++--- qpdf/qtest/qpdf/update-from-json-errors.out | 6 +++--- qpdf/qtest/qpdf/update-stream-data.json | 13 ++++++++----- qpdf/qtest/qpdf/update-stream-dict-only.json | 13 ++++++++----- qpdf/qtest/qpdf/various-updates.json | 13 ++++++++----- 63 files changed, 569 insertions(+), 249 deletions(-) create mode 100644 qpdf/qtest/qpdf/qjson-qpdf-array-too-long.json create mode 100644 qpdf/qtest/qpdf/qjson-qpdf-array-too-long.out create mode 100644 qpdf/qtest/qpdf/qjson-qpdf-not-array.json create mode 100644 qpdf/qtest/qpdf/qjson-qpdf-not-array.out diff --git a/TODO b/TODO index 61de004..3830a93 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 507ef61..6251d98 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 639e16c..943528b 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 ae71721..e09c0d7 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_str; if (this->m->test_json_schema) { diff --git a/libqpdf/QPDF_json.cc b/libqpdf/QPDF_json.cc index 81f21f8..9ecb1b3 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 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 92a89b6..0becd40 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 bc4c212..bfd3585 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 23edda2..abd9fa4 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 92f8b4b..012ab69 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 8b2c825..d0386ed 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 c90bbf0..72d73f0 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 78c5bef..82f50fa 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 78bbdbb..7b5fc55 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 2830f03..6e3fe19 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 a3f3c3c..9a9f3b8 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 518ae50..3ec8671 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 e09d040..b2a8a2d 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 5ee93e2..8a35a3f 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 1ad4dda..b8edda2 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 afbb696..9b28f8c 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 3fc0462..b6c4916 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 8114a26..e8f98d5 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 520ebe8..2c8ddb3 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 9b8880d..64ee805 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 025f700..614ea08 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 e863789..1b74d28 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 dee225f..bf33909 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 e99c26e..d4c5448 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 2f18da4..f364f1a 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 acc1642..f70cfb5 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 3a5086b..65be40c 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 ae28721..a5d6b48 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 2692a97..e5de89d 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 21050e0..e2fe9a1 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 3a4b791..de3793d 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 77bfe1c..53c5a72 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 6a00d76..a57ffb1 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 2adc33d..627421c 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 e739a2f..0263f29 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 93357af..c7f3abc 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 1268c83..5c77c88 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 12870f8..55288a3 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 b009ef6..219b00e 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 0000000..ed05b14 --- /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 0000000..065286d --- /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 0000000..68846ae --- /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 0000000..3122ba7 --- /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 a34e1a7..7f68f75 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 39b5207..a264839 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 fedf657..d6d368e 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 4d492bc..6a462ff 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 0617095..ee2b1b9 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 5a7ce0e..3b9d482 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 2b991a7..3e3a854 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 94a6087..a625cd6 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 4f69934..4666856 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 7004c2a..0c82470 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 97d71e1..417465a 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 2c535a0..743bff9 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 763579c..530d707 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 a650e93..ef89926 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 bc0a17c..93ec4af 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 80e3646..883eae8 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 @@ } } } - } + ] } -- libgit2 0.21.4