diff options
Diffstat (limited to 'libqpdf')
-rw-r--r-- | libqpdf/JSON.cc | 65 | ||||
-rw-r--r-- | libqpdf/QPDFAcroFormDocumentHelper.cc | 10 | ||||
-rw-r--r-- | libqpdf/QPDFEFStreamObjectHelper.cc | 2 | ||||
-rw-r--r-- | libqpdf/QPDFEmbeddedFileDocumentHelper.cc | 4 | ||||
-rw-r--r-- | libqpdf/QPDFJob.cc | 2 | ||||
-rw-r--r-- | libqpdf/QPDFObjectHandle.cc | 22 | ||||
-rw-r--r-- | libqpdf/QPDFPageObjectHelper.cc | 6 | ||||
-rw-r--r-- | libqpdf/QPDFWriter.cc | 4 |
8 files changed, 77 insertions, 38 deletions
diff --git a/libqpdf/JSON.cc b/libqpdf/JSON.cc index 1796c859..d380049f 100644 --- a/libqpdf/JSON.cc +++ b/libqpdf/JSON.cc @@ -538,26 +538,55 @@ JSON::checkSchemaInternal( } } } else if (sch_arr) { - if (!this_arr) { - QTC::TC("libtests", "JSON wanted array"); - errors.push_back(err_prefix + " is supposed to be an array"); - return false; - } - if (sch_arr->elements.size() != 1) { - QTC::TC("libtests", "JSON schema array error"); + auto n_elements = sch_arr->elements.size(); + if (n_elements == 1) { + // A single-element array in the schema allows a single + // element in the object or a variable-length array, each + // of whose items must conform to the single element of + // the schema array. This doesn't apply to arrays of + // arrays -- we fall back to the behavior of allowing a + // single item only when the object is not an array. + if (this_arr) { + int i = 0; + for (auto const& element: this_arr->elements) { + checkSchemaInternal( + element.get(), + sch_arr->elements.at(0).get(), + flags, + errors, + prefix + "." + QUtil::int_to_string(i)); + ++i; + } + } else { + QTC::TC("libtests", "JSON schema array for single item"); + checkSchemaInternal( + this_v, + sch_arr->elements.at(0).get(), + flags, + errors, + prefix); + } + } else if (!this_arr || (this_arr->elements.size() != n_elements)) { + QTC::TC("libtests", "JSON schema array length mismatch"); errors.push_back( - err_prefix + " schema array contains other than one item"); + err_prefix + " is supposed to be an array of length " + + QUtil::uint_to_string(n_elements)); return false; - } - int i = 0; - for (auto const& element: this_arr->elements) { - checkSchemaInternal( - element.get(), - sch_arr->elements.at(0).get(), - flags, - errors, - prefix + "." + QUtil::int_to_string(i)); - ++i; + } else { + // A multi-element array in the schema must correspond to + // an element of the same length in the object. Each + // element in the object is validated against the + // corresponding element in the schema. + size_t i = 0; + for (auto const& element: this_arr->elements) { + checkSchemaInternal( + element.get(), + sch_arr->elements.at(i).get(), + flags, + errors, + prefix + "." + QUtil::uint_to_string(i)); + ++i; + } } } else if (!sch_str) { QTC::TC("libtests", "JSON schema other type"); diff --git a/libqpdf/QPDFAcroFormDocumentHelper.cc b/libqpdf/QPDFAcroFormDocumentHelper.cc index 62dbaeee..23d021ff 100644 --- a/libqpdf/QPDFAcroFormDocumentHelper.cc +++ b/libqpdf/QPDFAcroFormDocumentHelper.cc @@ -40,7 +40,7 @@ QPDFAcroFormDocumentHelper::getOrCreateAcroForm() { auto acroform = this->qpdf.getRoot().getKey("/AcroForm"); if (!acroform.isDictionary()) { - acroform = this->qpdf.getRoot().replaceKeyAndGet( + acroform = this->qpdf.getRoot().replaceKeyAndGetNew( "/AcroForm", this->qpdf.makeIndirectObject(QPDFObjectHandle::newDictionary())); } @@ -53,8 +53,8 @@ QPDFAcroFormDocumentHelper::addFormField(QPDFFormFieldObjectHelper ff) auto acroform = getOrCreateAcroForm(); auto fields = acroform.getKey("/Fields"); if (!fields.isArray()) { - fields = - acroform.replaceKeyAndGet("/Fields", QPDFObjectHandle::newArray()); + fields = acroform.replaceKeyAndGetNew( + "/Fields", QPDFObjectHandle::newArray()); } fields.appendItem(ff.getObjectHandle()); std::set<QPDFObjGen> visited; @@ -854,7 +854,7 @@ QPDFAcroFormDocumentHelper::transformAnnotations( } dr.makeResourcesIndirect(this->qpdf); if (!dr.isIndirect()) { - dr = acroform.replaceKeyAndGet( + dr = acroform.replaceKeyAndGetNew( "/DR", this->qpdf.makeIndirectObject(dr)); } // Merge the other document's /DR, creating a conflict @@ -1076,7 +1076,7 @@ QPDFAcroFormDocumentHelper::transformAnnotations( auto apdict = ah.getAppearanceDictionary(); std::vector<QPDFObjectHandle> streams; auto replace_stream = [](auto& dict, auto& key, auto& old) { - return dict.replaceKeyAndGet(key, old.copyStream()); + return dict.replaceKeyAndGetNew(key, old.copyStream()); }; if (apdict.isDictionary()) { for (auto& ap: apdict.ditems()) { diff --git a/libqpdf/QPDFEFStreamObjectHelper.cc b/libqpdf/QPDFEFStreamObjectHelper.cc index cbfe47a3..8380206d 100644 --- a/libqpdf/QPDFEFStreamObjectHelper.cc +++ b/libqpdf/QPDFEFStreamObjectHelper.cc @@ -28,7 +28,7 @@ QPDFEFStreamObjectHelper::setParam( { auto params = this->oh.getDict().getKey("/Params"); if (!params.isDictionary()) { - params = this->oh.getDict().replaceKeyAndGet( + params = this->oh.getDict().replaceKeyAndGetNew( "/Params", QPDFObjectHandle::newDictionary()); } params.replaceKey(pkey, pval); diff --git a/libqpdf/QPDFEmbeddedFileDocumentHelper.cc b/libqpdf/QPDFEmbeddedFileDocumentHelper.cc index 847a9786..fd706c27 100644 --- a/libqpdf/QPDFEmbeddedFileDocumentHelper.cc +++ b/libqpdf/QPDFEmbeddedFileDocumentHelper.cc @@ -62,8 +62,8 @@ QPDFEmbeddedFileDocumentHelper::initEmbeddedFiles() auto root = qpdf.getRoot(); auto names = root.getKey("/Names"); if (!names.isDictionary()) { - names = - root.replaceKeyAndGet("/Names", QPDFObjectHandle::newDictionary()); + names = root.replaceKeyAndGetNew( + "/Names", QPDFObjectHandle::newDictionary()); } auto embedded_files = names.getKey("/EmbeddedFiles"); if (!embedded_files.isDictionary()) { diff --git a/libqpdf/QPDFJob.cc b/libqpdf/QPDFJob.cc index 26425def..2cbabac0 100644 --- a/libqpdf/QPDFJob.cc +++ b/libqpdf/QPDFJob.cc @@ -2100,7 +2100,7 @@ QPDFJob::doUnderOverlayForPage( QPDFObjectHandle resources = dest_page.getAttribute("/Resources", true); if (!resources.isDictionary()) { QTC::TC("qpdf", "QPDFJob overlay page with no resources"); - resources = dest_page.getObjectHandle().replaceKeyAndGet( + resources = dest_page.getObjectHandle().replaceKeyAndGetNew( "/Resources", QPDFObjectHandle::newDictionary()); } for (int from_pageno: pagenos[pageno]) { diff --git a/libqpdf/QPDFObjectHandle.cc b/libqpdf/QPDFObjectHandle.cc index bfbc19f9..135b7c39 100644 --- a/libqpdf/QPDFObjectHandle.cc +++ b/libqpdf/QPDFObjectHandle.cc @@ -915,7 +915,7 @@ QPDFObjectHandle::insertItem(int at, QPDFObjectHandle const& item) } QPDFObjectHandle -QPDFObjectHandle::insertItemAndGet(int at, QPDFObjectHandle const& item) +QPDFObjectHandle::insertItemAndGetNew(int at, QPDFObjectHandle const& item) { insertItem(at, item); return item; @@ -934,7 +934,7 @@ QPDFObjectHandle::appendItem(QPDFObjectHandle const& item) } QPDFObjectHandle -QPDFObjectHandle::appendItemAndGet(QPDFObjectHandle const& item) +QPDFObjectHandle::appendItemAndGetNew(QPDFObjectHandle const& item) { appendItem(item); return item; @@ -957,7 +957,7 @@ QPDFObjectHandle::eraseItem(int at) } QPDFObjectHandle -QPDFObjectHandle::eraseItemAndGet(int at) +QPDFObjectHandle::eraseItemAndGetOld(int at) { auto result = QPDFObjectHandle::newNull(); if (isArray() && (at < getArrayNItems()) && (at >= 0)) { @@ -1113,7 +1113,8 @@ QPDFObjectHandle::mergeResources( // subdictionaries just to get this shallow copy // functionality. QTC::TC("qpdf", "QPDFObjectHandle replace with copy"); - this_val = replaceKeyAndGet(rtype, this_val.shallowCopy()); + this_val = + replaceKeyAndGetNew(rtype, this_val.shallowCopy()); } std::map<QPDFObjGen, std::string> og_to_name; std::set<std::string> rnames; @@ -1242,13 +1243,22 @@ QPDFObjectHandle::replaceKey( } QPDFObjectHandle -QPDFObjectHandle::replaceKeyAndGet( +QPDFObjectHandle::replaceKeyAndGetNew( std::string const& key, QPDFObjectHandle const& value) { replaceKey(key, value); return value; } +QPDFObjectHandle +QPDFObjectHandle::replaceKeyAndGetOld( + std::string const& key, QPDFObjectHandle const& value) +{ + QPDFObjectHandle old = removeKeyAndGetOld(key); + replaceKey(key, value); + return old; +} + void QPDFObjectHandle::removeKey(std::string const& key) { @@ -1261,7 +1271,7 @@ QPDFObjectHandle::removeKey(std::string const& key) } QPDFObjectHandle -QPDFObjectHandle::removeKeyAndGet(std::string const& key) +QPDFObjectHandle::removeKeyAndGetOld(std::string const& key) { auto result = QPDFObjectHandle::newNull(); if (isDictionary()) { diff --git a/libqpdf/QPDFPageObjectHelper.cc b/libqpdf/QPDFPageObjectHelper.cc index 96a8ce69..9ad75cf8 100644 --- a/libqpdf/QPDFPageObjectHelper.cc +++ b/libqpdf/QPDFPageObjectHelper.cc @@ -595,7 +595,7 @@ QPDFPageObjectHelper::removeUnreferencedResourcesHelper( for (auto const& iter: to_filter) { QPDFObjectHandle dict = resources.getKey(iter); if (dict.isDictionary()) { - dict = resources.replaceKeyAndGet(iter, dict.shallowCopy()); + dict = resources.replaceKeyAndGetNew(iter, dict.shallowCopy()); rdicts.push_back(dict); auto keys = dict.getKeys(); known_names.insert(keys.begin(), keys.end()); @@ -1110,8 +1110,8 @@ QPDFPageObjectHelper::copyAnnotations( afdh->addAndRenameFormFields(new_fields); auto annots = this->oh.getKey("/Annots"); if (!annots.isArray()) { - annots = - this->oh.replaceKeyAndGet("/Annots", QPDFObjectHandle::newArray()); + annots = this->oh.replaceKeyAndGetNew( + "/Annots", QPDFObjectHandle::newArray()); } for (auto const& annot: new_annots) { annots.appendItem(annot); diff --git a/libqpdf/QPDFWriter.cc b/libqpdf/QPDFWriter.cc index b227e95a..e33d0965 100644 --- a/libqpdf/QPDFWriter.cc +++ b/libqpdf/QPDFWriter.cc @@ -1571,7 +1571,7 @@ QPDFWriter::unparseObject( "qpdf", "QPDFWriter create Extensions", this->m->qdf_mode ? 0 : 1); - extensions = object.replaceKeyAndGet( + extensions = object.replaceKeyAndGetNew( "/Extensions", QPDFObjectHandle::newDictionary()); } } else if (!have_extensions_other) { @@ -2277,7 +2277,7 @@ QPDFWriter::prepareFileForWrite() if (oh.isIndirect()) { QTC::TC("qpdf", "QPDFWriter make Extensions direct"); extensions_indirect = true; - oh = root.replaceKeyAndGet(key, oh.shallowCopy()); + oh = root.replaceKeyAndGetNew(key, oh.shallowCopy()); } if (oh.hasKey("/ADBE")) { QPDFObjectHandle adbe = oh.getKey("/ADBE"); |