From 16f4f94cd99b4d0f633596074e8d9358db135517 Mon Sep 17 00:00:00 2001 From: Jay Berkenbilt Date: Sat, 7 May 2022 07:53:45 -0400 Subject: [PATCH] Prepare code for JSON v2 Update getJSON() methods and calls to them --- TODO | 2 - fuzz/qpdf_fuzzer.cc | 2 +- include/qpdf/JSON.hh | 2 + include/qpdf/QPDFJob.hh | 5 ++ include/qpdf/QPDFObject.hh | 2 +- include/qpdf/QPDFObjectHandle.hh | 47 ++++++++-- job.sums | 6 +- job.yml | 1 + libqpdf/QPDFJob.cc | 89 ++++++++++++------- libqpdf/QPDFJob_config.cc | 4 +- libqpdf/QPDFObjectHandle.cc | 9 +- libqpdf/QPDF_Array.cc | 4 +- libqpdf/QPDF_Bool.cc | 2 +- libqpdf/QPDF_Dictionary.cc | 5 +- libqpdf/QPDF_InlineImage.cc | 2 +- libqpdf/QPDF_Integer.cc | 2 +- libqpdf/QPDF_Name.cc | 2 +- libqpdf/QPDF_Null.cc | 2 +- libqpdf/QPDF_Operator.cc | 2 +- libqpdf/QPDF_Real.cc | 2 +- libqpdf/QPDF_Reserved.cc | 2 +- libqpdf/QPDF_Stream.cc | 5 +- libqpdf/QPDF_String.cc | 3 +- libqpdf/qpdf/QPDF_Array.hh | 2 +- libqpdf/qpdf/QPDF_Bool.hh | 2 +- libqpdf/qpdf/QPDF_Dictionary.hh | 2 +- libqpdf/qpdf/QPDF_InlineImage.hh | 2 +- libqpdf/qpdf/QPDF_Integer.hh | 2 +- libqpdf/qpdf/QPDF_Name.hh | 2 +- libqpdf/qpdf/QPDF_Null.hh | 2 +- libqpdf/qpdf/QPDF_Operator.hh | 2 +- libqpdf/qpdf/QPDF_Real.hh | 2 +- libqpdf/qpdf/QPDF_Reserved.hh | 2 +- libqpdf/qpdf/QPDF_Stream.hh | 2 +- libqpdf/qpdf/QPDF_String.hh | 2 +- libqpdf/qpdf/auto_job_init.hh | 2 +- libqpdf/qpdf/auto_job_json_init.hh | 2 +- libtests/json.cc | 10 ++- qpdf/qtest/qpdf.test | 2 +- qpdf/qtest/qpdf/direct-pages-json-objects.out | 2 +- qpdf/qtest/qpdf/direct-pages-json-pages.out | 2 +- .../qpdf/optimize-images-defaults-json.out | 2 +- .../optimize-images-image-streams-json.out | 2 +- ...ize-images-inline-images-all-size-json.out | 2 +- .../optimize-images-inline-images-json.out | 2 +- ...ize-images-inline-images-keep-all-json.out | 2 +- ...ze-images-inline-images-keep-some-json.out | 2 +- .../optimize-images-min-area-all-json.out | 2 +- .../qpdf/optimize-images-min-area-json.out | 2 +- .../qpdf/optimize-images-min-height-json.out | 2 +- .../qpdf/optimize-images-min-width-json.out | 2 +- .../qpdf/optimize-images-unsupported-json.out | 2 +- qpdf/qtest/qpdf/page_api_2-json-objects.out | 2 +- qpdf/qtest/qpdf/page_api_2-json-pages.out | 2 +- qpdf/test_driver.cc | 4 +- 55 files changed, 177 insertions(+), 99 deletions(-) diff --git a/TODO b/TODO index 7ec4085e..db022f5a 100644 --- a/TODO +++ b/TODO @@ -50,8 +50,6 @@ Output JSON v2 General things to remember: -* deprecate getJSON without a version - * Make sure all the information from --check and other informational options (--show-linearization, --show-encryption, --show-xref, --list-attachments, --show-npages) is available in the json output. diff --git a/fuzz/qpdf_fuzzer.cc b/fuzz/qpdf_fuzzer.cc index a89eb1fa..367f85be 100644 --- a/fuzz/qpdf_fuzzer.cc +++ b/fuzz/qpdf_fuzzer.cc @@ -142,7 +142,7 @@ FuzzHelper::testPages() page.getImages(); pldh.getLabelForPage(pageno); QPDFObjectHandle page_obj(page.getObjectHandle()); - page_obj.getJSON(true).unparse(); + page_obj.getJSON(JSON::LATEST, true).unparse(); odh.getOutlinesForPage(page_obj.getObjGen()); std::vector annotations = diff --git a/include/qpdf/JSON.hh b/include/qpdf/JSON.hh index fdacd442..79f2a25f 100644 --- a/include/qpdf/JSON.hh +++ b/include/qpdf/JSON.hh @@ -51,6 +51,8 @@ class InputSource; class JSON { public: + static int constexpr LATEST = 2; + QPDF_DLL std::string unparse() const; diff --git a/include/qpdf/QPDFJob.hh b/include/qpdf/QPDFJob.hh index 352348ab..b664ab50 100644 --- a/include/qpdf/QPDFJob.hh +++ b/include/qpdf/QPDFJob.hh @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -520,6 +521,10 @@ class QPDFJob void doJSONAcroform(Pipeline* p, bool& first, QPDF& pdf); void doJSONEncrypt(Pipeline* p, bool& first, QPDF& pdf); void doJSONAttachments(Pipeline* p, bool& first, QPDF& pdf); + void addOutlinesToJson( + std::vector outlines, + JSON& j, + std::map& page_numbers); enum remove_unref_e { re_auto, re_yes, re_no }; diff --git a/include/qpdf/QPDFObject.hh b/include/qpdf/QPDFObject.hh index 43146e53..982cd126 100644 --- a/include/qpdf/QPDFObject.hh +++ b/include/qpdf/QPDFObject.hh @@ -64,7 +64,7 @@ class QPDFObject virtual ~QPDFObject() = default; virtual std::string unparse() = 0; - virtual JSON getJSON() = 0; + virtual JSON getJSON(int json_version) = 0; // Return a unique type code for the object virtual object_type_e getTypeCode() const = 0; diff --git a/include/qpdf/QPDFObjectHandle.hh b/include/qpdf/QPDFObjectHandle.hh index 77bef52b..82f4e365 100644 --- a/include/qpdf/QPDFObjectHandle.hh +++ b/include/qpdf/QPDFObjectHandle.hh @@ -1304,15 +1304,40 @@ class QPDFObjectHandle QPDF_DLL std::string unparseBinary(); - // Return encoded as JSON. For most object types, there is an - // obvious mapping. The JSON is generated as follows: - // * Names are encoded as strings representing the normalized name - // in PDF syntax as returned by unparse() + // Return encoded as JSON. The constant JSON::LATEST can be used + // to specify the latest available JSON version. The JSON is + // generated as follows: + // * Arrays, dictionaries, booleans, nulls, integers, and real + // numbers are represented by their native JSON types. + // * Names are encoded as strings representing the canonical + // representation (after parsing #xx) and preceded by a slash, + // just as unparse() returns. For example, the JSON for the + // PDF-syntax name /Text#2fPlain would be "/Text/Plain". // * Indirect references are encoded as strings containing "obj gen R" - // * Strings are encoded as UTF-8 strings with unrepresentable binary - // characters encoded as \uHHHH - // * Encoding streams just encodes the stream's dictionary; the stream - // data is not represented + // * Strings + // * JSON v1: Strings are encoded as UTF-8 strings with + // unrepresentable binary characters encoded as \uHHHH. + // Characters in PDF Doc encoding that don't have + // bidirectional unicode mappings are not reversible. There is + // no way to tell the difference between a string that looks + // like a name or indirect object from an actual name or + // indirect object. + // * JSON v2: + // * Unicode strings and strings encoded with PDF Doc encoding + // that can be bidrectionally mapped two Unicode (which is + // all strings without undefined characters) are represented + // as "u:" followed by the UTF-8 encoded string. Example: + // "u:potato". + // * All other strings are represented as "b:" followed by a + // hexadecimal encoding of the string. Example: "b:0102cacb" + // * Streams + // * JSON v1: Only the stream's dictionary is encoded. There is + // no way tell a stream from a dictionary other than context. + // * JSON v2: A stream is encoded as {"dict": {...}} with the + // value being the encoding of the stream's dictionary. Since + // "dict" does not otherwise represent anything, this is + // unambiguous. The getStreamJSON() call can be used to add + // encoding of the stream's data. // * Object types that are only valid in content streams (inline // image, operator) as well as "reserved" objects are not // representable and will be serialized as "null". @@ -1321,6 +1346,12 @@ class QPDFObjectHandle // dereference_indirect applies only to this object. It is not // recursive. QPDF_DLL + JSON getJSON(int json_version, bool dereference_indirect = false); + + // Deprecated version uses v1 for backward compatibility. + // ABI: remove for qpdf 12 + [[deprecated("Use getJSON(int version)")]] + QPDF_DLL JSON getJSON(bool dereference_indirect = false); // Legacy helper methods for commonly performed operations on diff --git a/job.sums b/job.sums index b59e0cff..eb2c54a3 100644 --- a/job.sums +++ b/job.sums @@ -6,12 +6,12 @@ include/qpdf/auto_job_c_enc.hh 28446f3c32153a52afa239ea40503e6cc8ac2c026813526a3 include/qpdf/auto_job_c_main.hh 940aa6f1ead18ed08ba33f11254e9f042348262c85b91de742f0427094412a80 include/qpdf/auto_job_c_pages.hh b3cc0f21029f6d89efa043dcdbfa183cb59325b6506001c18911614fe8e568ec include/qpdf/auto_job_c_uo.hh ae21b69a1efa9333050f4833d465f6daff87e5b38e5106e49bbef5d4132e4ed1 -job.yml 3c130913b3546f272c06b334ece9aa70450449539db10e39673b5ee79d863f48 +job.yml e3d9752ea8810872447190b0b2b913f591ae03dfdd876945adf1bbb76942cd0f libqpdf/qpdf/auto_job_decl.hh 74df4d7fdbdf51ecd0d58ce1e9844bb5525b9adac5a45f7c9a787ecdda2868df libqpdf/qpdf/auto_job_help.hh a3d1a326a3f8ff61a7d451176acde3bb6c8ad66c1ea7a0b8c5d789917ad3a9ee -libqpdf/qpdf/auto_job_init.hh c8477a597f037d7de5fd131b008a75f1fe435bba248261abe422e8bfb24c8755 +libqpdf/qpdf/auto_job_init.hh 1dcefadac02bb4b3a5d112912483902ad46489b1cacefefd3ebe4f64fc1b8a29 libqpdf/qpdf/auto_job_json_decl.hh 06caa46eaf71db8a50c046f91866baa8087745a9474319fb7c86d92634cc8297 -libqpdf/qpdf/auto_job_json_init.hh e7047a7c83737adfaae49abc295a579bb9b9e0a4644e911d1656a604cb202208 +libqpdf/qpdf/auto_job_json_init.hh 784ff973e7efbf589f6a9b3ad22b3aada5c5393e9c5cd31845b8fe4af6e03f98 libqpdf/qpdf/auto_job_schema.hh cbbcae166cfecbdbdeb40c5a30870e03604a019a8b4f7a217d554a82431d2e5f manual/_ext/qpdf.py 6add6321666031d55ed4aedf7c00e5662bba856dfcd66ccb526563bffefbb580 manual/cli.rst 8684ca1f601f2832cded52d1b2f74730f97b7b85b57e31a399231731fbe80d26 diff --git a/job.yml b/job.yml index 5e9000b2..c449520e 100644 --- a/job.yml +++ b/job.yml @@ -38,6 +38,7 @@ choices: - screen json_version: - 1 + - 2 - latest json_key: # The list of selectable top-level keys id duplicated in the diff --git a/libqpdf/QPDFJob.cc b/libqpdf/QPDFJob.cc index 78c678b0..5b493101 100644 --- a/libqpdf/QPDFJob.cc +++ b/libqpdf/QPDFJob.cc @@ -1053,12 +1053,20 @@ QPDFJob::doJSONObjects(Pipeline* p, bool& first, QPDF& pdf) for (auto& obj: objects) { if (all_objects || wanted_og.count(obj.getObjGen())) { JSON::writeDictionaryItem( - p, first_object, obj.unparse(), obj.getJSON(true), 1); + p, + first_object, + obj.unparse(), + obj.getJSON(this->m->json_version, true), + 1); } } if (all_objects || m->json_objects.count("trailer")) { JSON::writeDictionaryItem( - p, first_object, "trailer", pdf.getTrailer().getJSON(true), 1); + p, + first_object, + "trailer", + pdf.getTrailer().getJSON(this->m->json_version, true), + 1); } JSON::writeDictionaryClose(p, first_object, 1); } @@ -1080,11 +1088,13 @@ QPDFJob::doJSONObjectinfo(Pipeline* p, bool& first, QPDF& pdf) j_stream.addDictionaryMember("is", JSON::makeBool(is_stream)); j_stream.addDictionaryMember( "length", - (is_stream ? obj.getDict().getKey("/Length").getJSON(true) + (is_stream ? obj.getDict().getKey("/Length").getJSON( + this->m->json_version, true) : JSON::makeNull())); j_stream.addDictionaryMember( "filter", - (is_stream ? obj.getDict().getKey("/Filter").getJSON(true) + (is_stream ? obj.getDict().getKey("/Filter").getJSON( + this->m->json_version, true) : JSON::makeNull())); JSON::writeDictionaryItem( p, first_object, obj.unparse(), j_details, 1); @@ -1108,7 +1118,8 @@ QPDFJob::doJSONPages(Pipeline* p, bool& first, QPDF& pdf) ++pageno; JSON j_page = JSON::makeDictionary(); QPDFObjectHandle page = ph.getObjectHandle(); - j_page.addDictionaryMember("object", page.getJSON()); + j_page.addDictionaryMember( + "object", page.getJSON(this->m->json_version)); JSON j_images = j_page.addDictionaryMember("images", JSON::makeArray()); std::map images = ph.getImages(); for (auto const& iter2: images) { @@ -1116,17 +1127,23 @@ QPDFJob::doJSONPages(Pipeline* p, bool& first, QPDF& pdf) j_image.addDictionaryMember("name", JSON::makeString(iter2.first)); QPDFObjectHandle image = iter2.second; QPDFObjectHandle dict = image.getDict(); - j_image.addDictionaryMember("object", image.getJSON()); j_image.addDictionaryMember( - "width", dict.getKey("/Width").getJSON()); + "object", image.getJSON(this->m->json_version)); j_image.addDictionaryMember( - "height", dict.getKey("/Height").getJSON()); + "width", dict.getKey("/Width").getJSON(this->m->json_version)); j_image.addDictionaryMember( - "colorspace", dict.getKey("/ColorSpace").getJSON()); + "height", + dict.getKey("/Height").getJSON(this->m->json_version)); j_image.addDictionaryMember( - "bitspercomponent", dict.getKey("/BitsPerComponent").getJSON()); + "colorspace", + dict.getKey("/ColorSpace").getJSON(this->m->json_version)); + j_image.addDictionaryMember( + "bitspercomponent", + dict.getKey("/BitsPerComponent") + .getJSON(this->m->json_version)); QPDFObjectHandle filters = dict.getKey("/Filter").wrapInArray(); - j_image.addDictionaryMember("filter", filters.getJSON()); + j_image.addDictionaryMember( + "filter", filters.getJSON(this->m->json_version)); QPDFObjectHandle decode_parms = dict.getKey("/DecodeParms"); QPDFObjectHandle dp_array; if (decode_parms.isArray()) { @@ -1137,7 +1154,8 @@ QPDFJob::doJSONPages(Pipeline* p, bool& first, QPDF& pdf) dp_array.appendItem(decode_parms); } } - j_image.addDictionaryMember("decodeparms", dp_array.getJSON()); + j_image.addDictionaryMember( + "decodeparms", dp_array.getJSON(this->m->json_version)); j_image.addDictionaryMember( "filterable", JSON::makeBool( @@ -1148,10 +1166,11 @@ QPDFJob::doJSONPages(Pipeline* p, bool& first, QPDF& pdf) j_page.addDictionaryMember("contents", JSON::makeArray()); std::vector content = ph.getPageContents(); for (auto& iter2: content) { - j_contents.addArrayElement(iter2.getJSON()); + j_contents.addArrayElement(iter2.getJSON(this->m->json_version)); } j_page.addDictionaryMember( - "label", pldh.getLabelForPage(pageno).getJSON()); + "label", + pldh.getLabelForPage(pageno).getJSON(this->m->json_version)); JSON j_outlines = j_page.addDictionaryMember("outlines", JSON::makeArray()); std::vector outlines = @@ -1159,11 +1178,12 @@ QPDFJob::doJSONPages(Pipeline* p, bool& first, QPDF& pdf) for (auto& oiter: outlines) { JSON j_outline = j_outlines.addArrayElement(JSON::makeDictionary()); j_outline.addDictionaryMember( - "object", oiter.getObjectHandle().getJSON()); + "object", + oiter.getObjectHandle().getJSON(this->m->json_version)); j_outline.addDictionaryMember( "title", JSON::makeString(oiter.getTitle())); j_outline.addDictionaryMember( - "dest", oiter.getDest().getJSON(true)); + "dest", oiter.getDest().getJSON(this->m->json_version, true)); } j_page.addDictionaryMember("pageposfrom1", JSON::makeInt(1 + pageno)); JSON::writeArrayItem(p, first_page, j_page, 1); @@ -1192,25 +1212,29 @@ QPDFJob::doJSONPageLabels(Pipeline* p, bool& first, QPDF& pdf) break; } JSON j_label = j_labels.addArrayElement(JSON::makeDictionary()); - j_label.addDictionaryMember("index", (*iter).getJSON()); + j_label.addDictionaryMember( + "index", (*iter).getJSON(this->m->json_version)); ++iter; - j_label.addDictionaryMember("label", (*iter).getJSON()); + j_label.addDictionaryMember( + "label", (*iter).getJSON(this->m->json_version)); } } JSON::writeDictionaryItem(p, first, "pagelabels", j_labels, 0); } -static void -add_outlines_to_json( +void +QPDFJob::addOutlinesToJson( std::vector outlines, JSON& j, std::map& page_numbers) { for (auto& ol: outlines) { JSON jo = j.addArrayElement(JSON::makeDictionary()); - jo.addDictionaryMember("object", ol.getObjectHandle().getJSON()); + jo.addDictionaryMember( + "object", ol.getObjectHandle().getJSON(this->m->json_version)); jo.addDictionaryMember("title", JSON::makeString(ol.getTitle())); - jo.addDictionaryMember("dest", ol.getDest().getJSON(true)); + jo.addDictionaryMember( + "dest", ol.getDest().getJSON(this->m->json_version, true)); jo.addDictionaryMember("open", JSON::makeBool(ol.getCount() >= 0)); QPDFObjectHandle page = ol.getDestPage(); JSON j_destpage = JSON::makeNull(); @@ -1222,7 +1246,7 @@ add_outlines_to_json( } jo.addDictionaryMember("destpageposfrom1", j_destpage); JSON j_kids = jo.addDictionaryMember("kids", JSON::makeArray()); - add_outlines_to_json(ol.getKids(), j_kids, page_numbers); + addOutlinesToJson(ol.getKids(), j_kids, page_numbers); } } @@ -1240,7 +1264,7 @@ QPDFJob::doJSONOutlines(Pipeline* p, bool& first, QPDF& pdf) JSON j_outlines = JSON::makeArray(); QPDFOutlineDocumentHelper odh(pdf); - add_outlines_to_json(odh.getTopLevelOutlines(), j_outlines, page_numbers); + addOutlinesToJson(odh.getTopLevelOutlines(), j_outlines, page_numbers); JSON::writeDictionaryItem(p, first, "outlines", j_outlines, 0); } @@ -1265,9 +1289,11 @@ QPDFJob::doJSONAcroform(Pipeline* p, bool& first, QPDF& pdf) QPDFFormFieldObjectHelper ffh = afdh.getFieldForAnnotation(aoh); JSON j_field = j_fields.addArrayElement(JSON::makeDictionary()); j_field.addDictionaryMember( - "object", ffh.getObjectHandle().getJSON()); + "object", ffh.getObjectHandle().getJSON(this->m->json_version)); j_field.addDictionaryMember( - "parent", ffh.getObjectHandle().getKey("/Parent").getJSON()); + "parent", + ffh.getObjectHandle().getKey("/Parent").getJSON( + this->m->json_version)); j_field.addDictionaryMember( "pageposfrom1", JSON::makeInt(pagepos1)); j_field.addDictionaryMember( @@ -1282,9 +1308,11 @@ QPDFJob::doJSONAcroform(Pipeline* p, bool& first, QPDF& pdf) "alternativename", JSON::makeString(ffh.getAlternativeName())); j_field.addDictionaryMember( "mappingname", JSON::makeString(ffh.getMappingName())); - j_field.addDictionaryMember("value", ffh.getValue().getJSON()); j_field.addDictionaryMember( - "defaultvalue", ffh.getDefaultValue().getJSON()); + "value", ffh.getValue().getJSON(this->m->json_version)); + j_field.addDictionaryMember( + "defaultvalue", + ffh.getDefaultValue().getJSON(this->m->json_version)); j_field.addDictionaryMember( "quadding", JSON::makeInt(ffh.getQuadding())); j_field.addDictionaryMember( @@ -1303,7 +1331,7 @@ QPDFJob::doJSONAcroform(Pipeline* p, bool& first, QPDF& pdf) JSON j_annot = j_field.addDictionaryMember( "annotation", JSON::makeDictionary()); j_annot.addDictionaryMember( - "object", aoh.getObjectHandle().getJSON()); + "object", aoh.getObjectHandle().getJSON(this->m->json_version)); j_annot.addDictionaryMember( "appearancestate", JSON::makeString(aoh.getAppearanceState())); j_annot.addDictionaryMember( @@ -1621,7 +1649,8 @@ QPDFJob::doJSON(QPDF& pdf, Pipeline* p) // change is made to the JSON format. Clients of the JSON are to // ignore unrecognized keys, so we only update the version of a // key disappears or if its value changes meaning. - JSON::writeDictionaryItem(p, first, "version", JSON::makeInt(1), 0); + JSON::writeDictionaryItem( + p, first, "version", JSON::makeInt(this->m->json_version), 0); JSON j_params = JSON::makeDictionary(); std::string decode_level_str; switch (m->decode_level) { diff --git a/libqpdf/QPDFJob_config.cc b/libqpdf/QPDFJob_config.cc index 621499c1..3f8f0840 100644 --- a/libqpdf/QPDFJob_config.cc +++ b/libqpdf/QPDFJob_config.cc @@ -235,11 +235,11 @@ QPDFJob::Config* QPDFJob::Config::json(std::string const& parameter) { if (parameter.empty() || (parameter == "latest")) { - o.m->json_version = 1; + o.m->json_version = JSON::LATEST; } else { o.m->json_version = QUtil::string_to_int(parameter.c_str()); } - if (o.m->json_version != 1) { + if ((o.m->json_version < 1) || (o.m->json_version > JSON::LATEST)) { usage(std::string("unsupported json version ") + parameter); } o.m->require_outfile = false; diff --git a/libqpdf/QPDFObjectHandle.cc b/libqpdf/QPDFObjectHandle.cc index 05a0f30d..33155097 100644 --- a/libqpdf/QPDFObjectHandle.cc +++ b/libqpdf/QPDFObjectHandle.cc @@ -1775,8 +1775,15 @@ QPDFObjectHandle::unparseBinary() } } +// Deprecated versionless getJSON to be removed in qpdf 12 JSON QPDFObjectHandle::getJSON(bool dereference_indirect) +{ + return getJSON(1, dereference_indirect); +} + +JSON +QPDFObjectHandle::getJSON(int json_version, bool dereference_indirect) { if ((!dereference_indirect) && this->isIndirect()) { return JSON::makeString(unparse()); @@ -1786,7 +1793,7 @@ QPDFObjectHandle::getJSON(bool dereference_indirect) throw std::logic_error( "QPDFObjectHandle: attempting to unparse a reserved object"); } - return this->obj->getJSON(); + return this->obj->getJSON(json_version); } } diff --git a/libqpdf/QPDF_Array.cc b/libqpdf/QPDF_Array.cc index 8899bf6f..cb94d487 100644 --- a/libqpdf/QPDF_Array.cc +++ b/libqpdf/QPDF_Array.cc @@ -34,12 +34,12 @@ QPDF_Array::unparse() } JSON -QPDF_Array::getJSON() +QPDF_Array::getJSON(int json_version) { JSON j = JSON::makeArray(); size_t size = this->elements.size(); for (size_t i = 0; i < size; ++i) { - j.addArrayElement(this->elements.at(i).getJSON()); + j.addArrayElement(this->elements.at(i).getJSON(json_version)); } return j; } diff --git a/libqpdf/QPDF_Bool.cc b/libqpdf/QPDF_Bool.cc index e7cf7105..74d2ec3b 100644 --- a/libqpdf/QPDF_Bool.cc +++ b/libqpdf/QPDF_Bool.cc @@ -12,7 +12,7 @@ QPDF_Bool::unparse() } JSON -QPDF_Bool::getJSON() +QPDF_Bool::getJSON(int json_version) { return JSON::makeBool(this->val); } diff --git a/libqpdf/QPDF_Dictionary.cc b/libqpdf/QPDF_Dictionary.cc index 44b8a474..67d59a2d 100644 --- a/libqpdf/QPDF_Dictionary.cc +++ b/libqpdf/QPDF_Dictionary.cc @@ -32,13 +32,14 @@ QPDF_Dictionary::unparse() } JSON -QPDF_Dictionary::getJSON() +QPDF_Dictionary::getJSON(int json_version) { JSON j = JSON::makeDictionary(); for (auto& iter: this->items) { if (!iter.second.isNull()) { j.addDictionaryMember( - QPDF_Name::normalizeName(iter.first), iter.second.getJSON()); + QPDF_Name::normalizeName(iter.first), + iter.second.getJSON(json_version)); } } return j; diff --git a/libqpdf/QPDF_InlineImage.cc b/libqpdf/QPDF_InlineImage.cc index c9e65e63..84f4fa19 100644 --- a/libqpdf/QPDF_InlineImage.cc +++ b/libqpdf/QPDF_InlineImage.cc @@ -14,7 +14,7 @@ QPDF_InlineImage::unparse() } JSON -QPDF_InlineImage::getJSON() +QPDF_InlineImage::getJSON(int json_version) { return JSON::makeNull(); } diff --git a/libqpdf/QPDF_Integer.cc b/libqpdf/QPDF_Integer.cc index 9401b3f9..c42fa246 100644 --- a/libqpdf/QPDF_Integer.cc +++ b/libqpdf/QPDF_Integer.cc @@ -14,7 +14,7 @@ QPDF_Integer::unparse() } JSON -QPDF_Integer::getJSON() +QPDF_Integer::getJSON(int json_version) { return JSON::makeInt(this->val); } diff --git a/libqpdf/QPDF_Name.cc b/libqpdf/QPDF_Name.cc index 2e0dde97..8dc48faa 100644 --- a/libqpdf/QPDF_Name.cc +++ b/libqpdf/QPDF_Name.cc @@ -40,7 +40,7 @@ QPDF_Name::unparse() } JSON -QPDF_Name::getJSON() +QPDF_Name::getJSON(int json_version) { return JSON::makeString(normalizeName(this->name)); } diff --git a/libqpdf/QPDF_Null.cc b/libqpdf/QPDF_Null.cc index 0baff460..166b0302 100644 --- a/libqpdf/QPDF_Null.cc +++ b/libqpdf/QPDF_Null.cc @@ -7,7 +7,7 @@ QPDF_Null::unparse() } JSON -QPDF_Null::getJSON() +QPDF_Null::getJSON(int json_version) { return JSON::makeNull(); } diff --git a/libqpdf/QPDF_Operator.cc b/libqpdf/QPDF_Operator.cc index a8ccc970..f7da813a 100644 --- a/libqpdf/QPDF_Operator.cc +++ b/libqpdf/QPDF_Operator.cc @@ -14,7 +14,7 @@ QPDF_Operator::unparse() } JSON -QPDF_Operator::getJSON() +QPDF_Operator::getJSON(int json_version) { return JSON::makeNull(); } diff --git a/libqpdf/QPDF_Real.cc b/libqpdf/QPDF_Real.cc index 0af881eb..4b32b035 100644 --- a/libqpdf/QPDF_Real.cc +++ b/libqpdf/QPDF_Real.cc @@ -20,7 +20,7 @@ QPDF_Real::unparse() } JSON -QPDF_Real::getJSON() +QPDF_Real::getJSON(int json_version) { // While PDF allows .x or -.x, JSON does not. Rather than // converting from string to double and back, just handle this as a diff --git a/libqpdf/QPDF_Reserved.cc b/libqpdf/QPDF_Reserved.cc index 94bc584f..775dee02 100644 --- a/libqpdf/QPDF_Reserved.cc +++ b/libqpdf/QPDF_Reserved.cc @@ -10,7 +10,7 @@ QPDF_Reserved::unparse() } JSON -QPDF_Reserved::getJSON() +QPDF_Reserved::getJSON(int json_version) { throw std::logic_error("attempt to generate JSON from QPDF_Reserved"); return JSON::makeNull(); diff --git a/libqpdf/QPDF_Stream.cc b/libqpdf/QPDF_Stream.cc index 313eb835..8940b7cf 100644 --- a/libqpdf/QPDF_Stream.cc +++ b/libqpdf/QPDF_Stream.cc @@ -151,9 +151,10 @@ QPDF_Stream::unparse() } JSON -QPDF_Stream::getJSON() +QPDF_Stream::getJSON(int json_version) { - return this->stream_dict.getJSON(); + // QXXXQ + return this->stream_dict.getJSON(json_version); } QPDFObject::object_type_e diff --git a/libqpdf/QPDF_String.cc b/libqpdf/QPDF_String.cc index 30d6708b..fd820998 100644 --- a/libqpdf/QPDF_String.cc +++ b/libqpdf/QPDF_String.cc @@ -43,8 +43,9 @@ QPDF_String::unparse() } JSON -QPDF_String::getJSON() +QPDF_String::getJSON(int json_version) { + // QXXXQ return JSON::makeString(getUTF8Val()); } diff --git a/libqpdf/qpdf/QPDF_Array.hh b/libqpdf/qpdf/QPDF_Array.hh index eb310b8e..f45f8006 100644 --- a/libqpdf/qpdf/QPDF_Array.hh +++ b/libqpdf/qpdf/QPDF_Array.hh @@ -14,7 +14,7 @@ class QPDF_Array: public QPDFObject QPDF_Array(SparseOHArray const& items); virtual ~QPDF_Array() = default; virtual std::string unparse(); - virtual JSON getJSON(); + virtual JSON getJSON(int json_version); virtual QPDFObject::object_type_e getTypeCode() const; virtual char const* getTypeName() const; virtual void setDescription(QPDF*, std::string const&); diff --git a/libqpdf/qpdf/QPDF_Bool.hh b/libqpdf/qpdf/QPDF_Bool.hh index 87f44251..576b1505 100644 --- a/libqpdf/qpdf/QPDF_Bool.hh +++ b/libqpdf/qpdf/QPDF_Bool.hh @@ -9,7 +9,7 @@ class QPDF_Bool: public QPDFObject QPDF_Bool(bool val); virtual ~QPDF_Bool() = default; virtual std::string unparse(); - virtual JSON getJSON(); + virtual JSON getJSON(int json_version); virtual QPDFObject::object_type_e getTypeCode() const; virtual char const* getTypeName() const; bool getVal() const; diff --git a/libqpdf/qpdf/QPDF_Dictionary.hh b/libqpdf/qpdf/QPDF_Dictionary.hh index 3c42cc0e..16801a76 100644 --- a/libqpdf/qpdf/QPDF_Dictionary.hh +++ b/libqpdf/qpdf/QPDF_Dictionary.hh @@ -14,7 +14,7 @@ class QPDF_Dictionary: public QPDFObject QPDF_Dictionary(std::map const& items); virtual ~QPDF_Dictionary() = default; virtual std::string unparse(); - virtual JSON getJSON(); + virtual JSON getJSON(int json_version); virtual QPDFObject::object_type_e getTypeCode() const; virtual char const* getTypeName() const; virtual void setDescription(QPDF*, std::string const&); diff --git a/libqpdf/qpdf/QPDF_InlineImage.hh b/libqpdf/qpdf/QPDF_InlineImage.hh index ee79568b..32b25093 100644 --- a/libqpdf/qpdf/QPDF_InlineImage.hh +++ b/libqpdf/qpdf/QPDF_InlineImage.hh @@ -9,7 +9,7 @@ class QPDF_InlineImage: public QPDFObject QPDF_InlineImage(std::string const& val); virtual ~QPDF_InlineImage() = default; virtual std::string unparse(); - virtual JSON getJSON(); + virtual JSON getJSON(int json_version); virtual QPDFObject::object_type_e getTypeCode() const; virtual char const* getTypeName() const; std::string getVal() const; diff --git a/libqpdf/qpdf/QPDF_Integer.hh b/libqpdf/qpdf/QPDF_Integer.hh index 066629b6..36001a14 100644 --- a/libqpdf/qpdf/QPDF_Integer.hh +++ b/libqpdf/qpdf/QPDF_Integer.hh @@ -9,7 +9,7 @@ class QPDF_Integer: public QPDFObject QPDF_Integer(long long val); virtual ~QPDF_Integer() = default; virtual std::string unparse(); - virtual JSON getJSON(); + virtual JSON getJSON(int json_version); virtual QPDFObject::object_type_e getTypeCode() const; virtual char const* getTypeName() const; long long getVal() const; diff --git a/libqpdf/qpdf/QPDF_Name.hh b/libqpdf/qpdf/QPDF_Name.hh index 102cf4a3..5ee65d02 100644 --- a/libqpdf/qpdf/QPDF_Name.hh +++ b/libqpdf/qpdf/QPDF_Name.hh @@ -9,7 +9,7 @@ class QPDF_Name: public QPDFObject QPDF_Name(std::string const& name); virtual ~QPDF_Name() = default; virtual std::string unparse(); - virtual JSON getJSON(); + virtual JSON getJSON(int json_version); virtual QPDFObject::object_type_e getTypeCode() const; virtual char const* getTypeName() const; std::string getName() const; diff --git a/libqpdf/qpdf/QPDF_Null.hh b/libqpdf/qpdf/QPDF_Null.hh index 3ed6ddef..9d2d6223 100644 --- a/libqpdf/qpdf/QPDF_Null.hh +++ b/libqpdf/qpdf/QPDF_Null.hh @@ -8,7 +8,7 @@ class QPDF_Null: public QPDFObject public: virtual ~QPDF_Null() = default; virtual std::string unparse(); - virtual JSON getJSON(); + virtual JSON getJSON(int json_version); virtual QPDFObject::object_type_e getTypeCode() const; virtual char const* getTypeName() const; }; diff --git a/libqpdf/qpdf/QPDF_Operator.hh b/libqpdf/qpdf/QPDF_Operator.hh index 62a0e47b..672da728 100644 --- a/libqpdf/qpdf/QPDF_Operator.hh +++ b/libqpdf/qpdf/QPDF_Operator.hh @@ -9,7 +9,7 @@ class QPDF_Operator: public QPDFObject QPDF_Operator(std::string const& val); virtual ~QPDF_Operator() = default; virtual std::string unparse(); - virtual JSON getJSON(); + virtual JSON getJSON(int json_version); virtual QPDFObject::object_type_e getTypeCode() const; virtual char const* getTypeName() const; std::string getVal() const; diff --git a/libqpdf/qpdf/QPDF_Real.hh b/libqpdf/qpdf/QPDF_Real.hh index f12d6b3a..1b9878c7 100644 --- a/libqpdf/qpdf/QPDF_Real.hh +++ b/libqpdf/qpdf/QPDF_Real.hh @@ -10,7 +10,7 @@ class QPDF_Real: public QPDFObject QPDF_Real(double value, int decimal_places, bool trim_trailing_zeroes); virtual ~QPDF_Real() = default; virtual std::string unparse(); - virtual JSON getJSON(); + virtual JSON getJSON(int json_version); virtual QPDFObject::object_type_e getTypeCode() const; virtual char const* getTypeName() const; std::string getVal(); diff --git a/libqpdf/qpdf/QPDF_Reserved.hh b/libqpdf/qpdf/QPDF_Reserved.hh index e085f2d3..a198f645 100644 --- a/libqpdf/qpdf/QPDF_Reserved.hh +++ b/libqpdf/qpdf/QPDF_Reserved.hh @@ -8,7 +8,7 @@ class QPDF_Reserved: public QPDFObject public: virtual ~QPDF_Reserved() = default; virtual std::string unparse(); - virtual JSON getJSON(); + virtual JSON getJSON(int json_version); virtual QPDFObject::object_type_e getTypeCode() const; virtual char const* getTypeName() const; }; diff --git a/libqpdf/qpdf/QPDF_Stream.hh b/libqpdf/qpdf/QPDF_Stream.hh index ba456e76..5d8de669 100644 --- a/libqpdf/qpdf/QPDF_Stream.hh +++ b/libqpdf/qpdf/QPDF_Stream.hh @@ -25,7 +25,7 @@ class QPDF_Stream: public QPDFObject size_t length); virtual ~QPDF_Stream() = default; virtual std::string unparse(); - virtual JSON getJSON(); + virtual JSON getJSON(int json_version); virtual QPDFObject::object_type_e getTypeCode() const; virtual char const* getTypeName() const; virtual void setDescription(QPDF*, std::string const&); diff --git a/libqpdf/qpdf/QPDF_String.hh b/libqpdf/qpdf/QPDF_String.hh index 30be0c17..df33138c 100644 --- a/libqpdf/qpdf/QPDF_String.hh +++ b/libqpdf/qpdf/QPDF_String.hh @@ -15,7 +15,7 @@ class QPDF_String: public QPDFObject virtual QPDFObject::object_type_e getTypeCode() const; virtual char const* getTypeName() const; std::string unparse(bool force_binary); - virtual JSON getJSON(); + virtual JSON getJSON(int json_version); std::string getVal() const; std::string getUTF8Val() const; diff --git a/libqpdf/qpdf/auto_job_init.hh b/libqpdf/qpdf/auto_job_init.hh index 74155b80..b3191d4d 100644 --- a/libqpdf/qpdf/auto_job_init.hh +++ b/libqpdf/qpdf/auto_job_init.hh @@ -19,7 +19,7 @@ static char const* decode_level_choices[] = {"none", "generalized", "specialized static char const* object_streams_choices[] = {"disable", "preserve", "generate", 0}; static char const* remove_unref_choices[] = {"auto", "yes", "no", 0}; static char const* flatten_choices[] = {"all", "print", "screen", 0}; -static char const* json_version_choices[] = {"1", "latest", 0}; +static char const* json_version_choices[] = {"1", "2", "latest", 0}; static char const* json_key_choices[] = {"acroform", "attachments", "encrypt", "objectinfo", "objects", "outlines", "pagelabels", "pages", 0}; static char const* print128_choices[] = {"full", "low", "none", 0}; static char const* modify128_choices[] = {"all", "annotate", "form", "assembly", "none", 0}; diff --git a/libqpdf/qpdf/auto_job_json_init.hh b/libqpdf/qpdf/auto_job_json_init.hh index b2516469..92c4d65c 100644 --- a/libqpdf/qpdf/auto_job_json_init.hh +++ b/libqpdf/qpdf/auto_job_json_init.hh @@ -12,7 +12,7 @@ static char const* decode_level_choices[] = {"none", "generalized", "specialized static char const* object_streams_choices[] = {"disable", "preserve", "generate", 0}; static char const* remove_unref_choices[] = {"auto", "yes", "no", 0}; static char const* flatten_choices[] = {"all", "print", "screen", 0}; -static char const* json_version_choices[] = {"1", "latest", 0}; +static char const* json_version_choices[] = {"1", "2", "latest", 0}; static char const* json_key_choices[] = {"acroform", "attachments", "encrypt", "objectinfo", "objects", "outlines", "pagelabels", "pages", 0}; static char const* print128_choices[] = {"full", "low", "none", 0}; static char const* modify128_choices[] = {"all", "annotate", "form", "assembly", "none", 0}; diff --git a/libtests/json.cc b/libtests/json.cc index b386e6eb..46b4377d 100644 --- a/libtests/json.cc +++ b/libtests/json.cc @@ -100,10 +100,12 @@ test_main() " ],\n" " \"yes\": false\n" "}"); - check(QPDFObjectHandle::newReal("0.12").getJSON(), "0.12"); - check(QPDFObjectHandle::newReal(".34").getJSON(), "0.34"); - check(QPDFObjectHandle::newReal("-0.56").getJSON(), "-0.56"); - check(QPDFObjectHandle::newReal("-.78").getJSON(), "-0.78"); + for (int i = 1; i <= JSON::LATEST; ++i) { + check(QPDFObjectHandle::newReal("0.12").getJSON(i), "0.12"); + check(QPDFObjectHandle::newReal(".34").getJSON(i), "0.34"); + check(QPDFObjectHandle::newReal("-0.56").getJSON(i), "-0.56"); + check(QPDFObjectHandle::newReal("-.78").getJSON(i), "-0.78"); + } JSON jmap2 = JSON::parse(R"({"a": 1, "b": "two", "c": [true]})"); std::map dvalue; assert(jmap2.forEachDictItem( diff --git a/qpdf/qtest/qpdf.test b/qpdf/qtest/qpdf.test index 7d55bc30..369ceaf0 100644 --- a/qpdf/qtest/qpdf.test +++ b/qpdf/qtest/qpdf.test @@ -4279,7 +4279,7 @@ foreach my $d (@encrypted_files) my $enc_details = ""; my $enc_json = "{\n" . - " \"version\": 1,\n" . + " \"version\": 2,\n" . " \"parameters\": {\n" . " \"decodelevel\": \"generalized\"\n" . " },\n" . diff --git a/qpdf/qtest/qpdf/direct-pages-json-objects.out b/qpdf/qtest/qpdf/direct-pages-json-objects.out index 276ab18e..91b69e8b 100644 --- a/qpdf/qtest/qpdf/direct-pages-json-objects.out +++ b/qpdf/qtest/qpdf/direct-pages-json-objects.out @@ -1,5 +1,5 @@ { - "version": 1, + "version": 2, "parameters": { "decodelevel": "generalized" }, diff --git a/qpdf/qtest/qpdf/direct-pages-json-pages.out b/qpdf/qtest/qpdf/direct-pages-json-pages.out index fdea827b..57cc0cb7 100644 --- a/qpdf/qtest/qpdf/direct-pages-json-pages.out +++ b/qpdf/qtest/qpdf/direct-pages-json-pages.out @@ -1,5 +1,5 @@ { - "version": 1, + "version": 2, "parameters": { "decodelevel": "generalized" }, diff --git a/qpdf/qtest/qpdf/optimize-images-defaults-json.out b/qpdf/qtest/qpdf/optimize-images-defaults-json.out index a453b929..6b4ff1b4 100644 --- a/qpdf/qtest/qpdf/optimize-images-defaults-json.out +++ b/qpdf/qtest/qpdf/optimize-images-defaults-json.out @@ -1,5 +1,5 @@ { - "version": 1, + "version": 2, "parameters": { "decodelevel": "generalized" }, diff --git a/qpdf/qtest/qpdf/optimize-images-image-streams-json.out b/qpdf/qtest/qpdf/optimize-images-image-streams-json.out index 1412a6e1..054b8f87 100644 --- a/qpdf/qtest/qpdf/optimize-images-image-streams-json.out +++ b/qpdf/qtest/qpdf/optimize-images-image-streams-json.out @@ -1,5 +1,5 @@ { - "version": 1, + "version": 2, "parameters": { "decodelevel": "generalized" }, diff --git a/qpdf/qtest/qpdf/optimize-images-inline-images-all-size-json.out b/qpdf/qtest/qpdf/optimize-images-inline-images-all-size-json.out index cf495ba6..2817c3eb 100644 --- a/qpdf/qtest/qpdf/optimize-images-inline-images-all-size-json.out +++ b/qpdf/qtest/qpdf/optimize-images-inline-images-all-size-json.out @@ -1,5 +1,5 @@ { - "version": 1, + "version": 2, "parameters": { "decodelevel": "generalized" }, diff --git a/qpdf/qtest/qpdf/optimize-images-inline-images-json.out b/qpdf/qtest/qpdf/optimize-images-inline-images-json.out index cbaaf2d4..d0908966 100644 --- a/qpdf/qtest/qpdf/optimize-images-inline-images-json.out +++ b/qpdf/qtest/qpdf/optimize-images-inline-images-json.out @@ -1,5 +1,5 @@ { - "version": 1, + "version": 2, "parameters": { "decodelevel": "generalized" }, diff --git a/qpdf/qtest/qpdf/optimize-images-inline-images-keep-all-json.out b/qpdf/qtest/qpdf/optimize-images-inline-images-keep-all-json.out index 4c9c2e56..7e7e4b60 100644 --- a/qpdf/qtest/qpdf/optimize-images-inline-images-keep-all-json.out +++ b/qpdf/qtest/qpdf/optimize-images-inline-images-keep-all-json.out @@ -1,5 +1,5 @@ { - "version": 1, + "version": 2, "parameters": { "decodelevel": "generalized" }, diff --git a/qpdf/qtest/qpdf/optimize-images-inline-images-keep-some-json.out b/qpdf/qtest/qpdf/optimize-images-inline-images-keep-some-json.out index 8722ea5d..69e40f25 100644 --- a/qpdf/qtest/qpdf/optimize-images-inline-images-keep-some-json.out +++ b/qpdf/qtest/qpdf/optimize-images-inline-images-keep-some-json.out @@ -1,5 +1,5 @@ { - "version": 1, + "version": 2, "parameters": { "decodelevel": "generalized" }, diff --git a/qpdf/qtest/qpdf/optimize-images-min-area-all-json.out b/qpdf/qtest/qpdf/optimize-images-min-area-all-json.out index a453b929..6b4ff1b4 100644 --- a/qpdf/qtest/qpdf/optimize-images-min-area-all-json.out +++ b/qpdf/qtest/qpdf/optimize-images-min-area-all-json.out @@ -1,5 +1,5 @@ { - "version": 1, + "version": 2, "parameters": { "decodelevel": "generalized" }, diff --git a/qpdf/qtest/qpdf/optimize-images-min-area-json.out b/qpdf/qtest/qpdf/optimize-images-min-area-json.out index a453b929..6b4ff1b4 100644 --- a/qpdf/qtest/qpdf/optimize-images-min-area-json.out +++ b/qpdf/qtest/qpdf/optimize-images-min-area-json.out @@ -1,5 +1,5 @@ { - "version": 1, + "version": 2, "parameters": { "decodelevel": "generalized" }, diff --git a/qpdf/qtest/qpdf/optimize-images-min-height-json.out b/qpdf/qtest/qpdf/optimize-images-min-height-json.out index c9319058..aaf1d442 100644 --- a/qpdf/qtest/qpdf/optimize-images-min-height-json.out +++ b/qpdf/qtest/qpdf/optimize-images-min-height-json.out @@ -1,5 +1,5 @@ { - "version": 1, + "version": 2, "parameters": { "decodelevel": "generalized" }, diff --git a/qpdf/qtest/qpdf/optimize-images-min-width-json.out b/qpdf/qtest/qpdf/optimize-images-min-width-json.out index cbf44238..8b51602f 100644 --- a/qpdf/qtest/qpdf/optimize-images-min-width-json.out +++ b/qpdf/qtest/qpdf/optimize-images-min-width-json.out @@ -1,5 +1,5 @@ { - "version": 1, + "version": 2, "parameters": { "decodelevel": "generalized" }, diff --git a/qpdf/qtest/qpdf/optimize-images-unsupported-json.out b/qpdf/qtest/qpdf/optimize-images-unsupported-json.out index fdbd28fb..ca63d0c8 100644 --- a/qpdf/qtest/qpdf/optimize-images-unsupported-json.out +++ b/qpdf/qtest/qpdf/optimize-images-unsupported-json.out @@ -1,5 +1,5 @@ { - "version": 1, + "version": 2, "parameters": { "decodelevel": "generalized" }, diff --git a/qpdf/qtest/qpdf/page_api_2-json-objects.out b/qpdf/qtest/qpdf/page_api_2-json-objects.out index e97d6ef3..cc6d1630 100644 --- a/qpdf/qtest/qpdf/page_api_2-json-objects.out +++ b/qpdf/qtest/qpdf/page_api_2-json-objects.out @@ -1,5 +1,5 @@ { - "version": 1, + "version": 2, "parameters": { "decodelevel": "generalized" }, diff --git a/qpdf/qtest/qpdf/page_api_2-json-pages.out b/qpdf/qtest/qpdf/page_api_2-json-pages.out index 56aa5497..bf6a2d25 100644 --- a/qpdf/qtest/qpdf/page_api_2-json-pages.out +++ b/qpdf/qtest/qpdf/page_api_2-json-pages.out @@ -1,5 +1,5 @@ { - "version": 1, + "version": 2, "parameters": { "decodelevel": "generalized" }, diff --git a/qpdf/test_driver.cc b/qpdf/test_driver.cc index 849eb4a0..acd9049b 100644 --- a/qpdf/test_driver.cc +++ b/qpdf/test_driver.cc @@ -1922,7 +1922,7 @@ test_50(QPDF& pdf, char const* arg2) QPDFObjectHandle d1 = pdf.getTrailer().getKey("/Dict1"); QPDFObjectHandle d2 = pdf.getTrailer().getKey("/Dict2"); d1.mergeResources(d2); - std::cout << d1.getJSON().unparse() << std::endl; + std::cout << d1.getJSON(JSON::LATEST).unparse() << std::endl; // Top-level type mismatch d1.mergeResources(d2.getKey("/k1")); for (auto const& name: d1.getResourceNames()) { @@ -3114,7 +3114,7 @@ test_87(QPDF& pdf, char const* arg2) }); assert(dict.unparse() == "<< /A 2 >>"); assert(dict.getKeys() == std::set({"/A"})); - assert(dict.getJSON().unparse() == "{\n \"/A\": 2\n}"); + assert(dict.getJSON(JSON::LATEST).unparse() == "{\n \"/A\": 2\n}"); } static void