From 774584163ff3d310e7c932e2a6f63b590cb736ac Mon Sep 17 00:00:00 2001 From: Jay Berkenbilt Date: Thu, 27 Dec 2012 15:17:39 -0500 Subject: Add ExtensionLevel support to version handling All version operations are now fully aware of extension levels. --- include/qpdf/QPDF.hh | 2 + include/qpdf/QPDFWriter.hh | 12 +- libqpdf/QPDF.cc | 24 ++ libqpdf/QPDFWriter.cc | 279 +++++++++++++++++++-- qpdf/qpdf.cc | 38 ++- qpdf/qpdf.testcov | 13 +- qpdf/qtest/qpdf.test | 54 ++++ qpdf/qtest/qpdf/extensions-adbe-force-1.3.out | 4 + qpdf/qtest/qpdf/extensions-adbe-force-1.6.out | 4 + qpdf/qtest/qpdf/extensions-adbe-force-1.7.1.out | 4 + qpdf/qtest/qpdf/extensions-adbe-force-1.7.2.out | 4 + qpdf/qtest/qpdf/extensions-adbe-force-1.7.3.out | 4 + qpdf/qtest/qpdf/extensions-adbe-force-1.8.0.out | 4 + qpdf/qtest/qpdf/extensions-adbe-force-1.8.2.out | 4 + qpdf/qtest/qpdf/extensions-adbe-force-1.8.5.out | 4 + qpdf/qtest/qpdf/extensions-adbe-force-1.8.5.pdf | Bin 0 -> 865 bytes qpdf/qtest/qpdf/extensions-adbe-force-1.8.5.qdf | 104 ++++++++ qpdf/qtest/qpdf/extensions-adbe-force-1.8.out | 4 + qpdf/qtest/qpdf/extensions-adbe-min-1.3.out | 4 + qpdf/qtest/qpdf/extensions-adbe-min-1.6.out | 4 + qpdf/qtest/qpdf/extensions-adbe-min-1.7.1.out | 4 + qpdf/qtest/qpdf/extensions-adbe-min-1.7.2.out | 4 + qpdf/qtest/qpdf/extensions-adbe-min-1.7.3.out | 4 + qpdf/qtest/qpdf/extensions-adbe-min-1.8.0.out | 4 + qpdf/qtest/qpdf/extensions-adbe-min-1.8.2.out | 4 + qpdf/qtest/qpdf/extensions-adbe-min-1.8.5.out | 4 + qpdf/qtest/qpdf/extensions-adbe-min-1.8.out | 4 + .../qtest/qpdf/extensions-adbe-other-force-1.3.out | 4 + .../qtest/qpdf/extensions-adbe-other-force-1.6.out | 4 + .../qpdf/extensions-adbe-other-force-1.7.1.out | 4 + .../qpdf/extensions-adbe-other-force-1.7.2.out | 4 + .../qpdf/extensions-adbe-other-force-1.7.3.out | 4 + .../qpdf/extensions-adbe-other-force-1.8.0.out | 4 + .../qpdf/extensions-adbe-other-force-1.8.2.out | 4 + .../qpdf/extensions-adbe-other-force-1.8.5.out | 4 + .../qpdf/extensions-adbe-other-force-1.8.5.pdf | Bin 0 -> 923 bytes .../qpdf/extensions-adbe-other-force-1.8.5.qdf | 108 ++++++++ .../qtest/qpdf/extensions-adbe-other-force-1.8.out | 4 + qpdf/qtest/qpdf/extensions-adbe-other-min-1.3.out | 4 + qpdf/qtest/qpdf/extensions-adbe-other-min-1.6.out | 4 + .../qtest/qpdf/extensions-adbe-other-min-1.7.1.out | 4 + .../qtest/qpdf/extensions-adbe-other-min-1.7.2.out | 4 + .../qtest/qpdf/extensions-adbe-other-min-1.7.3.out | 4 + .../qtest/qpdf/extensions-adbe-other-min-1.8.0.out | 4 + .../qtest/qpdf/extensions-adbe-other-min-1.8.2.out | 4 + .../qtest/qpdf/extensions-adbe-other-min-1.8.5.out | 4 + qpdf/qtest/qpdf/extensions-adbe-other-min-1.8.out | 4 + qpdf/qtest/qpdf/extensions-adbe-other.pdf | 104 ++++++++ qpdf/qtest/qpdf/extensions-adbe.pdf | 106 ++++++++ qpdf/qtest/qpdf/extensions-none-force-1.3.out | 4 + qpdf/qtest/qpdf/extensions-none-force-1.6.out | 4 + qpdf/qtest/qpdf/extensions-none-force-1.7.1.out | 4 + qpdf/qtest/qpdf/extensions-none-force-1.7.2.out | 4 + qpdf/qtest/qpdf/extensions-none-force-1.7.3.out | 4 + qpdf/qtest/qpdf/extensions-none-force-1.8.0.out | 4 + qpdf/qtest/qpdf/extensions-none-force-1.8.2.out | 4 + qpdf/qtest/qpdf/extensions-none-force-1.8.5.out | 4 + qpdf/qtest/qpdf/extensions-none-force-1.8.5.pdf | Bin 0 -> 865 bytes qpdf/qtest/qpdf/extensions-none-force-1.8.5.qdf | 102 ++++++++ qpdf/qtest/qpdf/extensions-none-force-1.8.out | 4 + qpdf/qtest/qpdf/extensions-none-min-1.3.out | 4 + qpdf/qtest/qpdf/extensions-none-min-1.6.out | 4 + qpdf/qtest/qpdf/extensions-none-min-1.7.1.out | 4 + qpdf/qtest/qpdf/extensions-none-min-1.7.2.out | 4 + qpdf/qtest/qpdf/extensions-none-min-1.7.3.out | 4 + qpdf/qtest/qpdf/extensions-none-min-1.8.0.out | 4 + qpdf/qtest/qpdf/extensions-none-min-1.8.2.out | 4 + qpdf/qtest/qpdf/extensions-none-min-1.8.5.out | 4 + qpdf/qtest/qpdf/extensions-none-min-1.8.out | 4 + qpdf/qtest/qpdf/extensions-other-force-1.3.out | 4 + qpdf/qtest/qpdf/extensions-other-force-1.6.out | 4 + qpdf/qtest/qpdf/extensions-other-force-1.7.1.out | 4 + qpdf/qtest/qpdf/extensions-other-force-1.7.2.out | 4 + qpdf/qtest/qpdf/extensions-other-force-1.7.3.out | 4 + qpdf/qtest/qpdf/extensions-other-force-1.8.0.out | 4 + qpdf/qtest/qpdf/extensions-other-force-1.8.2.out | 4 + qpdf/qtest/qpdf/extensions-other-force-1.8.5.out | 4 + qpdf/qtest/qpdf/extensions-other-force-1.8.5.pdf | Bin 0 -> 923 bytes qpdf/qtest/qpdf/extensions-other-force-1.8.5.qdf | 108 ++++++++ qpdf/qtest/qpdf/extensions-other-force-1.8.out | 4 + qpdf/qtest/qpdf/extensions-other-min-1.3.out | 4 + qpdf/qtest/qpdf/extensions-other-min-1.6.out | 4 + qpdf/qtest/qpdf/extensions-other-min-1.7.1.out | 4 + qpdf/qtest/qpdf/extensions-other-min-1.7.2.out | 4 + qpdf/qtest/qpdf/extensions-other-min-1.7.3.out | 4 + qpdf/qtest/qpdf/extensions-other-min-1.8.0.out | 4 + qpdf/qtest/qpdf/extensions-other-min-1.8.2.out | 4 + qpdf/qtest/qpdf/extensions-other-min-1.8.5.out | 4 + qpdf/qtest/qpdf/extensions-other-min-1.8.out | 4 + qpdf/qtest/qpdf/extensions-other.pdf | 98 ++++++++ qpdf/qtest/qpdf/obj0-check.out | 6 +- qpdf/test_driver.cc | 7 + 92 files changed, 1423 insertions(+), 30 deletions(-) create mode 100644 qpdf/qtest/qpdf/extensions-adbe-force-1.3.out create mode 100644 qpdf/qtest/qpdf/extensions-adbe-force-1.6.out create mode 100644 qpdf/qtest/qpdf/extensions-adbe-force-1.7.1.out create mode 100644 qpdf/qtest/qpdf/extensions-adbe-force-1.7.2.out create mode 100644 qpdf/qtest/qpdf/extensions-adbe-force-1.7.3.out create mode 100644 qpdf/qtest/qpdf/extensions-adbe-force-1.8.0.out create mode 100644 qpdf/qtest/qpdf/extensions-adbe-force-1.8.2.out create mode 100644 qpdf/qtest/qpdf/extensions-adbe-force-1.8.5.out create mode 100644 qpdf/qtest/qpdf/extensions-adbe-force-1.8.5.pdf create mode 100644 qpdf/qtest/qpdf/extensions-adbe-force-1.8.5.qdf create mode 100644 qpdf/qtest/qpdf/extensions-adbe-force-1.8.out create mode 100644 qpdf/qtest/qpdf/extensions-adbe-min-1.3.out create mode 100644 qpdf/qtest/qpdf/extensions-adbe-min-1.6.out create mode 100644 qpdf/qtest/qpdf/extensions-adbe-min-1.7.1.out create mode 100644 qpdf/qtest/qpdf/extensions-adbe-min-1.7.2.out create mode 100644 qpdf/qtest/qpdf/extensions-adbe-min-1.7.3.out create mode 100644 qpdf/qtest/qpdf/extensions-adbe-min-1.8.0.out create mode 100644 qpdf/qtest/qpdf/extensions-adbe-min-1.8.2.out create mode 100644 qpdf/qtest/qpdf/extensions-adbe-min-1.8.5.out create mode 100644 qpdf/qtest/qpdf/extensions-adbe-min-1.8.out create mode 100644 qpdf/qtest/qpdf/extensions-adbe-other-force-1.3.out create mode 100644 qpdf/qtest/qpdf/extensions-adbe-other-force-1.6.out create mode 100644 qpdf/qtest/qpdf/extensions-adbe-other-force-1.7.1.out create mode 100644 qpdf/qtest/qpdf/extensions-adbe-other-force-1.7.2.out create mode 100644 qpdf/qtest/qpdf/extensions-adbe-other-force-1.7.3.out create mode 100644 qpdf/qtest/qpdf/extensions-adbe-other-force-1.8.0.out create mode 100644 qpdf/qtest/qpdf/extensions-adbe-other-force-1.8.2.out create mode 100644 qpdf/qtest/qpdf/extensions-adbe-other-force-1.8.5.out create mode 100644 qpdf/qtest/qpdf/extensions-adbe-other-force-1.8.5.pdf create mode 100644 qpdf/qtest/qpdf/extensions-adbe-other-force-1.8.5.qdf create mode 100644 qpdf/qtest/qpdf/extensions-adbe-other-force-1.8.out create mode 100644 qpdf/qtest/qpdf/extensions-adbe-other-min-1.3.out create mode 100644 qpdf/qtest/qpdf/extensions-adbe-other-min-1.6.out create mode 100644 qpdf/qtest/qpdf/extensions-adbe-other-min-1.7.1.out create mode 100644 qpdf/qtest/qpdf/extensions-adbe-other-min-1.7.2.out create mode 100644 qpdf/qtest/qpdf/extensions-adbe-other-min-1.7.3.out create mode 100644 qpdf/qtest/qpdf/extensions-adbe-other-min-1.8.0.out create mode 100644 qpdf/qtest/qpdf/extensions-adbe-other-min-1.8.2.out create mode 100644 qpdf/qtest/qpdf/extensions-adbe-other-min-1.8.5.out create mode 100644 qpdf/qtest/qpdf/extensions-adbe-other-min-1.8.out create mode 100644 qpdf/qtest/qpdf/extensions-adbe-other.pdf create mode 100644 qpdf/qtest/qpdf/extensions-adbe.pdf create mode 100644 qpdf/qtest/qpdf/extensions-none-force-1.3.out create mode 100644 qpdf/qtest/qpdf/extensions-none-force-1.6.out create mode 100644 qpdf/qtest/qpdf/extensions-none-force-1.7.1.out create mode 100644 qpdf/qtest/qpdf/extensions-none-force-1.7.2.out create mode 100644 qpdf/qtest/qpdf/extensions-none-force-1.7.3.out create mode 100644 qpdf/qtest/qpdf/extensions-none-force-1.8.0.out create mode 100644 qpdf/qtest/qpdf/extensions-none-force-1.8.2.out create mode 100644 qpdf/qtest/qpdf/extensions-none-force-1.8.5.out create mode 100644 qpdf/qtest/qpdf/extensions-none-force-1.8.5.pdf create mode 100644 qpdf/qtest/qpdf/extensions-none-force-1.8.5.qdf create mode 100644 qpdf/qtest/qpdf/extensions-none-force-1.8.out create mode 100644 qpdf/qtest/qpdf/extensions-none-min-1.3.out create mode 100644 qpdf/qtest/qpdf/extensions-none-min-1.6.out create mode 100644 qpdf/qtest/qpdf/extensions-none-min-1.7.1.out create mode 100644 qpdf/qtest/qpdf/extensions-none-min-1.7.2.out create mode 100644 qpdf/qtest/qpdf/extensions-none-min-1.7.3.out create mode 100644 qpdf/qtest/qpdf/extensions-none-min-1.8.0.out create mode 100644 qpdf/qtest/qpdf/extensions-none-min-1.8.2.out create mode 100644 qpdf/qtest/qpdf/extensions-none-min-1.8.5.out create mode 100644 qpdf/qtest/qpdf/extensions-none-min-1.8.out create mode 100644 qpdf/qtest/qpdf/extensions-other-force-1.3.out create mode 100644 qpdf/qtest/qpdf/extensions-other-force-1.6.out create mode 100644 qpdf/qtest/qpdf/extensions-other-force-1.7.1.out create mode 100644 qpdf/qtest/qpdf/extensions-other-force-1.7.2.out create mode 100644 qpdf/qtest/qpdf/extensions-other-force-1.7.3.out create mode 100644 qpdf/qtest/qpdf/extensions-other-force-1.8.0.out create mode 100644 qpdf/qtest/qpdf/extensions-other-force-1.8.2.out create mode 100644 qpdf/qtest/qpdf/extensions-other-force-1.8.5.out create mode 100644 qpdf/qtest/qpdf/extensions-other-force-1.8.5.pdf create mode 100644 qpdf/qtest/qpdf/extensions-other-force-1.8.5.qdf create mode 100644 qpdf/qtest/qpdf/extensions-other-force-1.8.out create mode 100644 qpdf/qtest/qpdf/extensions-other-min-1.3.out create mode 100644 qpdf/qtest/qpdf/extensions-other-min-1.6.out create mode 100644 qpdf/qtest/qpdf/extensions-other-min-1.7.1.out create mode 100644 qpdf/qtest/qpdf/extensions-other-min-1.7.2.out create mode 100644 qpdf/qtest/qpdf/extensions-other-min-1.7.3.out create mode 100644 qpdf/qtest/qpdf/extensions-other-min-1.8.0.out create mode 100644 qpdf/qtest/qpdf/extensions-other-min-1.8.2.out create mode 100644 qpdf/qtest/qpdf/extensions-other-min-1.8.5.out create mode 100644 qpdf/qtest/qpdf/extensions-other-min-1.8.out create mode 100644 qpdf/qtest/qpdf/extensions-other.pdf diff --git a/include/qpdf/QPDF.hh b/include/qpdf/QPDF.hh index 00591ea5..866b11b3 100644 --- a/include/qpdf/QPDF.hh +++ b/include/qpdf/QPDF.hh @@ -144,6 +144,8 @@ class QPDF QPDF_DLL std::string getPDFVersion() const; QPDF_DLL + int getExtensionLevel(); + QPDF_DLL QPDFObjectHandle getTrailer(); QPDF_DLL QPDFObjectHandle getRoot(); diff --git a/include/qpdf/QPDFWriter.hh b/include/qpdf/QPDFWriter.hh index 89536e13..15963890 100644 --- a/include/qpdf/QPDFWriter.hh +++ b/include/qpdf/QPDFWriter.hh @@ -153,6 +153,8 @@ class QPDFWriter // streams are used. QPDF_DLL void setMinimumPDFVersion(std::string const&); + QPDF_DLL + void setMinimumPDFVersion(std::string const&, int extension_level); // Force the PDF version of the output file to be a given version. // Use of this function may create PDF files that will not work @@ -171,6 +173,8 @@ class QPDFWriter // object streams. QPDF_DLL void forcePDFVersion(std::string const&); + QPDF_DLL + void forcePDFVersion(std::string const&, int extension_level); // Provide additional text to insert in the PDF file somewhere // near the beginning of the file. This can be used to add @@ -251,6 +255,7 @@ class QPDFWriter static int const f_stream = 1 << 0; static int const f_filtered = 1 << 1; static int const f_in_ostream = 1 << 2; + static int const f_in_extensions = 1 << 3; enum trailer_e { t_normal, t_lin_first, t_lin_second }; @@ -286,7 +291,8 @@ class QPDFWriter char const* user_password, char const* owner_password, bool allow_accessibility, bool allow_extract, qpdf_r3_print_e print, qpdf_r3_modify_e modify); - void disableIncompatibleEncryption(int major, int minor); + void disableIncompatibleEncryption(int major, int minor, + int extension_level); void parseVersion(std::string const& version, int& major, int& minor) const; int compareVersions(int major1, int minor1, int major2, int minor2) const; void setEncryptionParameters( @@ -375,8 +381,12 @@ class QPDFWriter std::string id1; // for /ID key of std::string id2; // trailer dictionary + std::string final_pdf_version; + int final_extension_level; std::string min_pdf_version; + int min_extension_level; std::string forced_pdf_version; + int forced_extension_level; std::string extra_header_text; int encryption_dict_objid; std::string cur_data_key; diff --git a/libqpdf/QPDF.cc b/libqpdf/QPDF.cc index fac79796..9d5d8240 100644 --- a/libqpdf/QPDF.cc +++ b/libqpdf/QPDF.cc @@ -1872,6 +1872,30 @@ QPDF::getPDFVersion() const return this->pdf_version; } +int +QPDF::getExtensionLevel() +{ + int result = 0; + QPDFObjectHandle obj = getRoot(); + if (obj.hasKey("/Extensions")) + { + obj = obj.getKey("/Extensions"); + if (obj.isDictionary() && obj.hasKey("/ADBE")) + { + obj = obj.getKey("/ADBE"); + if (obj.isDictionary() && obj.hasKey("/ExtensionLevel")) + { + obj = obj.getKey("/ExtensionLevel"); + if (obj.isInteger()) + { + result = obj.getIntValue(); + } + } + } + } + return result; +} + QPDFObjectHandle QPDF::getTrailer() { diff --git a/libqpdf/QPDFWriter.cc b/libqpdf/QPDFWriter.cc index f893053b..963f9627 100644 --- a/libqpdf/QPDFWriter.cc +++ b/libqpdf/QPDFWriter.cc @@ -64,6 +64,9 @@ QPDFWriter::init() object_stream_mode = qpdf_o_preserve; encrypt_metadata = true; encrypt_use_aes = false; + min_extension_level = 0; + final_extension_level = 0; + forced_extension_level = 0; encryption_dict_objid = 0; next_objid = 1; cur_stream_length_id = 0; @@ -169,11 +172,20 @@ QPDFWriter::setQDFMode(bool val) void QPDFWriter::setMinimumPDFVersion(std::string const& version) +{ + setMinimumPDFVersion(version, 0); +} + +void +QPDFWriter::setMinimumPDFVersion(std::string const& version, + int extension_level) { bool set_version = false; + bool set_extension_level = false; if (this->min_pdf_version.empty()) { set_version = true; + set_extension_level = true; } else { @@ -183,10 +195,22 @@ QPDFWriter::setMinimumPDFVersion(std::string const& version) int min_minor = 0; parseVersion(version, old_major, old_minor); parseVersion(this->min_pdf_version, min_major, min_minor); - if (compareVersions(old_major, old_minor, min_major, min_minor) > 0) + int compare = compareVersions( + old_major, old_minor, min_major, min_minor); + if (compare > 0) { - QTC::TC("qpdf", "QPDFWriter increasing minimum version"); + QTC::TC("qpdf", "QPDFWriter increasing minimum version", + extension_level == 0 ? 0 : 1); set_version = true; + set_extension_level = true; + } + else if (compare == 0) + { + if (extension_level > this->min_extension_level) + { + QTC::TC("qpdf", "QPDFWriter increasing extension level"); + set_extension_level = true; + } } } @@ -194,12 +218,24 @@ QPDFWriter::setMinimumPDFVersion(std::string const& version) { this->min_pdf_version = version; } + if (set_extension_level) + { + this->min_extension_level = extension_level; + } } void QPDFWriter::forcePDFVersion(std::string const& version) +{ + forcePDFVersion(version, 0); +} + +void +QPDFWriter::forcePDFVersion(std::string const& version, + int extension_level) { this->forced_pdf_version = version; + this->forced_extension_level = extension_level; } void @@ -476,7 +512,8 @@ QPDFWriter::copyEncryptionParameters(QPDF& qpdf) } void -QPDFWriter::disableIncompatibleEncryption(int major, int minor) +QPDFWriter::disableIncompatibleEncryption(int major, int minor, + int extension_level) { if (! this->encrypted) { @@ -513,6 +550,15 @@ QPDFWriter::disableIncompatibleEncryption(int major, int minor) disable = true; } } + else if ((compareVersions(major, minor, 1, 7) < 0) || + ((compareVersions(major, minor, 1, 7) == 0) && + extension_level < 3)) + { + if ((V >= 5) || (R >= 5)) + { + disable = true; + } + } } if (disable) { @@ -584,15 +630,26 @@ QPDFWriter::setEncryptionParametersInternal( encryption_dictionary["/P"] = QUtil::int_to_string(P); encryption_dictionary["/O"] = QPDF_String(O).unparse(true); encryption_dictionary["/U"] = QPDF_String(U).unparse(true); - setMinimumPDFVersion("1.3"); - if (R == 3) + if (V >= 5) { setMinimumPDFVersion("1.4"); } - else if (R >= 4) + if (R >= 5) + { + setMinimumPDFVersion("1.7", 3); + } + else if (R == 4) { setMinimumPDFVersion(this->encrypt_use_aes ? "1.6" : "1.5"); } + else if (R == 3) + { + setMinimumPDFVersion("1.4"); + } + else + { + setMinimumPDFVersion("1.3"); + } if ((R >= 4) && (! encrypt_metadata)) { @@ -1005,7 +1062,7 @@ QPDFWriter::unparseObject(QPDFObjectHandle object, int level, unsigned int flags, size_t stream_length, bool compress) { - unsigned int child_flags = flags & ~f_stream; + unsigned int child_flags = flags & ~f_stream & ~f_in_extensions; std::string indent; for (int i = 0; i < level; ++i) @@ -1037,8 +1094,143 @@ QPDFWriter::unparseObject(QPDFObjectHandle object, int level, } else if (object.isDictionary()) { + // Handle special cases for specific dictionaries. + + // Extensions dictionaries are complicated. We have one of + // several cases: + // + // * We need ADBE + // - We already have Extensions + // - If it has the right ADBE, preserve it + // - Otherwise, replace ADBE + // - We don't have Extensions: create one from scratch + // * We don't want ADBE + // - We already have Extensions + // - If it only has ADBE, remove it + // - If it has other things, keep those and remove ADBE + // - We have no extensions: no action required + // + // We may be in the root dictionary, or we may be inside the + // extensions dictionary itself. The latter is determined by + // the presence of the f_in_extensions flag. + + bool is_root = false; + bool have_extensions_other = false; + bool have_extensions_adbe = false; + + QPDFObjectHandle extensions; + if (object.getObjectID() == pdf.getRoot().getObjectID()) + { + is_root = true; + if (object.hasKey("/Extensions") && + object.getKey("/Extensions").isDictionary()) + { + extensions = object.getKey("/Extensions"); + } + } + else if (flags & f_in_extensions) + { + extensions = object; + } + if (extensions.isInitialized()) + { + std::set keys = extensions.getKeys(); + if (keys.count("/ADBE") > 0) + { + have_extensions_adbe = true; + keys.erase("/ADBE"); + } + if (keys.size() > 0) + { + have_extensions_other = true; + } + } + + bool need_extensions_adbe = (this->final_extension_level > 0); + + bool write_new_extensions = false; + bool write_new_adbe = false; + bool suppress_existing_extensions = false; + bool suppress_existing_adbe = false; + if (is_root) + { + if (need_extensions_adbe) + { + if (! (have_extensions_other || have_extensions_adbe)) + { + // We need Extensions and don't have it. Create + // it here. + QTC::TC("qpdf", "QPDFWriter create Extensions", + this->qdf_mode ? 0 : 1); + write_new_extensions = true; + suppress_existing_extensions = true; + } + else + { + // Preserve existing Extensions and do the work + // in the extensions dictionary. + } + } + else if (! have_extensions_other) + { + // We have Extensions dictionary and don't want one. + suppress_existing_extensions = true; + if (have_extensions_adbe) + { + QTC::TC("qpdf", "QPDFWriter remove existing Extensions"); + } + } + } + else if (flags & f_in_extensions) + { + QTC::TC("qpdf", "QPDFWriter preserve Extensions"); + QPDFObjectHandle adbe = extensions.getKey("/ADBE"); + if (adbe.isDictionary() && + adbe.hasKey("/BaseVersion") && + adbe.getKey("/BaseVersion").isName() && + (adbe.getKey("/BaseVersion").getName() == + "/" + this->final_pdf_version) && + adbe.hasKey("/ExtensionLevel") && + adbe.getKey("/ExtensionLevel").isInteger() && + (adbe.getKey("/ExtensionLevel").getIntValue() == + this->final_extension_level)) + { + QTC::TC("qpdf", "QPDFWriter preserve ADBE"); + } + else + { + suppress_existing_adbe = true; + if (need_extensions_adbe) + { + write_new_adbe = true; + } + } + } + writeString("<<"); writeStringQDF("\n"); + + if (write_new_extensions || write_new_adbe) + { + writeStringQDF(indent); + writeStringQDF(" "); + writeStringNoQDF(" "); + if (write_new_extensions) + { + writeString("/Extensions << "); + } + writeString("/ADBE << /BaseVersion /"); + writeString(this->final_pdf_version); + writeString(" /ExtensionLevel "); + writeString(QUtil::int_to_string(this->final_extension_level)); + writeString(" >>"); + if (write_new_extensions) + { + writeString(" >>"); + } + writeStringQDF("\n"); + } + std::set keys = object.getKeys(); for (std::set::iterator iter = keys.begin(); iter != keys.end(); ++iter) @@ -1057,12 +1249,27 @@ QPDFWriter::unparseObject(QPDFObjectHandle object, int level, { continue; } + + bool is_extensions = (is_root && (key == "/Extensions")); + if (suppress_existing_extensions && is_extensions) + { + QTC::TC("qpdf", "QPDFWriter skip Extensions"); + continue; + } + if (suppress_existing_adbe && (key == "/ADBE")) + { + QTC::TC("qpdf", "QPDFWriter skip ADBE"); + continue; + } + + writeStringQDF(indent); writeStringQDF(" "); writeStringNoQDF(" "); writeString(QPDF_Name::normalizeName(key)); writeString(" "); - unparseChild(object.getKey(key), level + 1, child_flags); + unparseChild(object.getKey(key), level + 1, + child_flags | (is_extensions ? f_in_extensions : 0)); writeStringQDF("\n"); } @@ -1706,12 +1913,17 @@ QPDFWriter::prepareFileForWrite() else if (node.isDictionary() || node.isStream()) { bool is_stream = false; + bool is_root = false; QPDFObjectHandle dict = node; if (node.isStream()) { is_stream = true; dict = node.getDict(); } + else if (pdf.getRoot().getObjectID() == node.getObjectID()) + { + is_root = true; + } std::set keys = dict.getKeys(); for (std::set::iterator iter = keys.begin(); @@ -1720,19 +1932,43 @@ QPDFWriter::prepareFileForWrite() std::string const& key = *iter; QPDFObjectHandle oh = dict.getKey(key); bool add_to_queue = true; - if (oh.isIndirect()) + if (is_stream) + { + if (oh.isIndirect() && + ((key == "/Length") || + (key == "/Filter") || + (key == "/DecodeParms"))) + { + QTC::TC("qpdf", "QPDFWriter make stream key direct"); + add_to_queue = false; + oh.makeDirect(); + dict.replaceKey(key, oh); + } + } + else if (is_root) { - if (is_stream) + if ((key == "/Extensions") && (oh.isDictionary())) { - if ((key == "/Length") || - (key == "/Filter") || - (key == "/DecodeParms")) + bool extensions_indirect = false; + if (oh.isIndirect()) { - QTC::TC("qpdf", "QPDF make stream key direct"); + QTC::TC("qpdf", "QPDFWriter make Extensions direct"); + extensions_indirect = true; add_to_queue = false; - oh.makeDirect(); + oh = oh.shallowCopy(); dict.replaceKey(key, oh); } + if (oh.hasKey("/ADBE")) + { + QPDFObjectHandle adbe = oh.getKey("/ADBE"); + if (adbe.isIndirect()) + { + QTC::TC("qpdf", "QPDFWriter make ADBE direct", + extensions_indirect ? 0 : 1); + adbe.makeDirect(); + oh.replaceKey("/ADBE", adbe); + } + } } } @@ -1791,7 +2027,8 @@ QPDFWriter::write() int major = 0; int minor = 0; parseVersion(this->forced_pdf_version, major, minor); - disableIncompatibleEncryption(major, minor); + disableIncompatibleEncryption(major, minor, + this->forced_extension_level); if (compareVersions(major, minor, 1, 5) < 0) { QTC::TC("qpdf", "QPDFWriter forcing object stream disable"); @@ -1938,16 +2175,18 @@ QPDFWriter::writeEncryptionDictionary() void QPDFWriter::writeHeader() { - setMinimumPDFVersion(pdf.getPDFVersion()); - std::string version = this->min_pdf_version; + setMinimumPDFVersion(pdf.getPDFVersion(), pdf.getExtensionLevel()); + this->final_pdf_version = this->min_pdf_version; + this->final_extension_level = this->min_extension_level; if (! this->forced_pdf_version.empty()) { QTC::TC("qpdf", "QPDFWriter using forced PDF version"); - version = this->forced_pdf_version; + this->final_pdf_version = this->forced_pdf_version; + this->final_extension_level = this->forced_extension_level; } writeString("%PDF-"); - writeString(version); + writeString(this->final_pdf_version); // This string of binary characters would not be valid UTF-8, so // it really should be treated as binary. writeString("\n%\xbf\xf7\xa2\xfe\n"); diff --git a/qpdf/qpdf.cc b/qpdf/qpdf.cc index ddb2ad69..e5b47494 100644 --- a/qpdf/qpdf.cc +++ b/qpdf/qpdf.cc @@ -189,6 +189,9 @@ familiar with the PDF file format or who are PDF developers.\n\ --min-version=version sets the minimum PDF version of the output file\n\ --force-version=version forces this to be the PDF version of the output file\n\ \n\ +Version numbers may be expressed as major.minor.extension-level, so 1.7.3\n\ +means PDF version 1.7 at extension level 3.\n\ +\n\ Values for stream data options:\n\ \n\ compress recompress stream data when possible (default)\n\ @@ -838,6 +841,21 @@ QPDFPageData::QPDFPageData(QPDF* qpdf, char const* range) : this->selected_pages = parse_numrange(range, (int)this->orig_pages.size()); } +static void parse_version(std::string const& full_version_string, + std::string& version, int& extension_level) +{ + PointerHolder vp(true, QUtil::copy_string(full_version_string)); + char* v = vp.getPointer(); + char* p1 = strchr(v, '.'); + char* p2 = (p1 ? strchr(1 + p1, '.') : 0); + if (p2 && *(p2 + 1)) + { + *p2++ = '\0'; + extension_level = atoi(p2); + } + version = v; +} + int main(int argc, char* argv[]) { whoami = QUtil::getWhoami(argv[0]); @@ -1370,8 +1388,14 @@ int main(int argc, char* argv[]) std::cout << "checking " << infilename << std::endl; try { - std::cout << "PDF Version: " << pdf.getPDFVersion() - << std::endl; + int extension_level = pdf.getExtensionLevel(); + std::cout << "PDF Version: " << pdf.getPDFVersion(); + if (extension_level > 0) + { + std::cout << " extension level " + << pdf.getExtensionLevel(); + } + std::cout << std::endl; ::show_encryption(pdf); if (pdf.isLinearized()) { @@ -1603,11 +1627,17 @@ int main(int argc, char* argv[]) } if (! min_version.empty()) { - w.setMinimumPDFVersion(min_version); + std::string version; + int extension_level = 0; + parse_version(min_version, version, extension_level); + w.setMinimumPDFVersion(version, extension_level); } if (! force_version.empty()) { - w.forcePDFVersion(force_version); + std::string version; + int extension_level = 0; + parse_version(force_version, version, extension_level); + w.forcePDFVersion(version, extension_level); } w.write(); } diff --git a/qpdf/qpdf.testcov b/qpdf/qpdf.testcov index bad9bbf7..1f8238e0 100644 --- a/qpdf/qpdf.testcov +++ b/qpdf/qpdf.testcov @@ -151,7 +151,7 @@ qpdf-c called qpdf_allow_modify_form 0 qpdf-c called qpdf_allow_modify_annotation 0 qpdf-c called qpdf_allow_modify_other 0 qpdf-c called qpdf_allow_modify_all 0 -QPDFWriter increasing minimum version 0 +QPDFWriter increasing minimum version 1 QPDFWriter using forced PDF version 0 qpdf-c called qpdf_set_minimum_pdf_version 0 qpdf-c called qpdf_force_pdf_version 0 @@ -243,4 +243,13 @@ QPDFWriter extra header text no newline 0 QPDFWriter extra header text add newline 0 QPDF bogus 0 offset 0 QPDF global offset 0 -QPDF make stream key direct 0 +QPDFWriter make stream key direct 0 +QPDFWriter increasing extension level 0 +QPDFWriter make Extensions direct 0 +QPDFWriter make ADBE direct 1 +QPDFWriter preserve Extensions 0 +QPDFWriter create Extensions 1 +QPDFWriter skip ADBE 0 +QPDFWriter remove existing Extensions 0 +QPDFWriter skip Extensions 0 +QPDFWriter preserve ADBE 0 diff --git a/qpdf/qtest/qpdf.test b/qpdf/qtest/qpdf.test index e06ac221..cf73c992 100644 --- a/qpdf/qtest/qpdf.test +++ b/qpdf/qtest/qpdf.test @@ -109,6 +109,55 @@ $td->runtest("new stream", {$td->FILE => "a.pdf"}, {$td->FILE => "add-contents.pdf"}); +show_ntests(); +# ---------- +$td->notify("--- Extensions Dictionary Tests ---"); +my @ext_inputs = ('minimal.pdf', 'extensions-adbe.pdf', + 'extensions-other.pdf', 'extensions-adbe-other.pdf'); +my @new_versions = ('1.3', '1.6', '1.7.1', '1.7.2', '1.7.3', + '1.8', '1.8.0', '1.8.2', '1.8.5'); +$n_tests += (4 * @new_versions + 3) * @ext_inputs; +foreach my $input (@ext_inputs) +{ + my $base = $input; + $base =~ s/\.pdf$//; + if ($base eq 'minimal') + { + $base = 'extensions-none'; + } + foreach my $version (@new_versions) + { + foreach my $op (qw(min force)) + { + $td->runtest("$input: $op version to $version", + {$td->COMMAND => + "qpdf --static-id" . + " --$op-version=$version $input a.pdf"}, + {$td->STRING => "", $td->EXIT_STATUS => 0}); + $td->runtest("check version information", + {$td->COMMAND => "test_driver 34 a.pdf"}, + {$td->FILE => "$base-$op-$version.out", + $td->EXIT_STATUS => 0}, + $td->NORMALIZE_NEWLINES); + if (($op eq 'force') && ($version eq '1.8.5')) + { + # Look at the actual file for a few cases to make sure + # qdf and non-qdf output are okay + $td->runtest("check file", + {$td->FILE => "a.pdf"}, + {$td->FILE => "$base-$op-$version.pdf"}); + $td->runtest("$input: $op version to $version", + {$td->COMMAND => + "qpdf --qdf --static-id" . + " --$op-version=$version $input a.qdf"}, + {$td->STRING => "", $td->EXIT_STATUS => 0}); + $td->runtest("check file", + {$td->FILE => "a.qdf"}, + {$td->FILE => "$base-$op-$version.qdf"}); + } + } + } +} show_ntests(); # ---------- $td->notify("--- Page API Tests ---"); @@ -147,6 +196,7 @@ $td->runtest("remove page we don't have", {$td->COMMAND => "test_driver 22 page_api_1.pdf"}, {$td->FILE => "page_api_1.out2", $td->EXIT_STATUS => 2}, $td->NORMALIZE_NEWLINES); +show_ntests(); # ---------- $td->notify("--- Miscellaneous Tests ---"); $n_tests += 57; @@ -466,6 +516,7 @@ foreach my $d (@nrange_tests) $td->NORMALIZE_NEWLINES); } +show_ntests(); # ---------- $td->notify("--- Merging and Splitting ---"); $n_tests += 6; @@ -513,6 +564,7 @@ $td->runtest("avoid respecification of password", $td->runtest("check output", {$td->FILE => "a.pdf"}, {$td->FILE => "pages-copy-encryption.pdf"}); +show_ntests(); # ---------- $td->notify("--- PDF From Scratch ---"); $n_tests += 2; @@ -524,6 +576,7 @@ $td->runtest("basic qpdf from scratch", $td->runtest("check output", {$td->FILE => "a.pdf"}, {$td->FILE => "from-scratch-0.pdf"}); +show_ntests(); # ---------- $td->notify("--- Copy Foreign Objects ---"); $n_tests += 7; @@ -546,6 +599,7 @@ $td->runtest("copy objects error", {$td->FILE => "copy-foreign-objects-errors.out", $td->EXIT_STATUS => 0}, $td->NORMALIZE_NEWLINES); +show_ntests(); # ---------- $td->notify("--- Error Condition Tests ---"); # $n_tests incremented after initialization of badfiles below. diff --git a/qpdf/qtest/qpdf/extensions-adbe-force-1.3.out b/qpdf/qtest/qpdf/extensions-adbe-force-1.3.out new file mode 100644 index 00000000..3795c645 --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-adbe-force-1.3.out @@ -0,0 +1,4 @@ +version: 1.3 +extension level: 0 +null +test 34 done diff --git a/qpdf/qtest/qpdf/extensions-adbe-force-1.6.out b/qpdf/qtest/qpdf/extensions-adbe-force-1.6.out new file mode 100644 index 00000000..762063b9 --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-adbe-force-1.6.out @@ -0,0 +1,4 @@ +version: 1.6 +extension level: 0 +null +test 34 done diff --git a/qpdf/qtest/qpdf/extensions-adbe-force-1.7.1.out b/qpdf/qtest/qpdf/extensions-adbe-force-1.7.1.out new file mode 100644 index 00000000..96168639 --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-adbe-force-1.7.1.out @@ -0,0 +1,4 @@ +version: 1.7 +extension level: 1 +<< /ADBE << /BaseVersion /1.7 /ExtensionLevel 1 >> >> +test 34 done diff --git a/qpdf/qtest/qpdf/extensions-adbe-force-1.7.2.out b/qpdf/qtest/qpdf/extensions-adbe-force-1.7.2.out new file mode 100644 index 00000000..4571bf2e --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-adbe-force-1.7.2.out @@ -0,0 +1,4 @@ +version: 1.7 +extension level: 2 +<< /ADBE << /BaseVersion /1.7 /ExtensionLevel 2 /URL (http://something.adobe.com) >> >> +test 34 done diff --git a/qpdf/qtest/qpdf/extensions-adbe-force-1.7.3.out b/qpdf/qtest/qpdf/extensions-adbe-force-1.7.3.out new file mode 100644 index 00000000..76321208 --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-adbe-force-1.7.3.out @@ -0,0 +1,4 @@ +version: 1.7 +extension level: 3 +<< /ADBE << /BaseVersion /1.7 /ExtensionLevel 3 >> >> +test 34 done diff --git a/qpdf/qtest/qpdf/extensions-adbe-force-1.8.0.out b/qpdf/qtest/qpdf/extensions-adbe-force-1.8.0.out new file mode 100644 index 00000000..491fdb7e --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-adbe-force-1.8.0.out @@ -0,0 +1,4 @@ +version: 1.8 +extension level: 0 +null +test 34 done diff --git a/qpdf/qtest/qpdf/extensions-adbe-force-1.8.2.out b/qpdf/qtest/qpdf/extensions-adbe-force-1.8.2.out new file mode 100644 index 00000000..7823a1dd --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-adbe-force-1.8.2.out @@ -0,0 +1,4 @@ +version: 1.8 +extension level: 2 +<< /ADBE << /BaseVersion /1.8 /ExtensionLevel 2 >> >> +test 34 done diff --git a/qpdf/qtest/qpdf/extensions-adbe-force-1.8.5.out b/qpdf/qtest/qpdf/extensions-adbe-force-1.8.5.out new file mode 100644 index 00000000..2d78af7e --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-adbe-force-1.8.5.out @@ -0,0 +1,4 @@ +version: 1.8 +extension level: 5 +<< /ADBE << /BaseVersion /1.8 /ExtensionLevel 5 >> >> +test 34 done diff --git a/qpdf/qtest/qpdf/extensions-adbe-force-1.8.5.pdf b/qpdf/qtest/qpdf/extensions-adbe-force-1.8.5.pdf new file mode 100644 index 00000000..7dbab516 Binary files /dev/null and b/qpdf/qtest/qpdf/extensions-adbe-force-1.8.5.pdf differ diff --git a/qpdf/qtest/qpdf/extensions-adbe-force-1.8.5.qdf b/qpdf/qtest/qpdf/extensions-adbe-force-1.8.5.qdf new file mode 100644 index 00000000..111ed12a --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-adbe-force-1.8.5.qdf @@ -0,0 +1,104 @@ +%PDF-1.8 +%¿÷¢þ +%QDF-1.0 + +%% Original object ID: 1 0 +1 0 obj +<< + /Extensions << + /ADBE << /BaseVersion /1.8 /ExtensionLevel 5 >> + >> + /Pages 2 0 R + /Type /Catalog +>> +endobj + +%% Original object ID: 2 0 +2 0 obj +<< + /Count 1 + /Kids [ + 3 0 R + ] + /Type /Pages +>> +endobj + +%% Page 1 +%% Original object ID: 3 0 +3 0 obj +<< + /Contents 4 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 2 0 R + /Resources << + /Font << + /F1 6 0 R + >> + /ProcSet 7 0 R + >> + /Type /Page +>> +endobj + +%% Contents for page 1 +%% Original object ID: 4 0 +4 0 obj +<< + /Length 5 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Potato) Tj +ET +endstream +endobj + +5 0 obj +44 +endobj + +%% Original object ID: 6 0 +6 0 obj +<< + /BaseFont /Helvetica + /Encoding /WinAnsiEncoding + /Name /F1 + /Subtype /Type1 + /Type /Font +>> +endobj + +%% Original object ID: 7 0 +7 0 obj +[ + /PDF + /Text +] +endobj + +xref +0 8 +0000000000 65535 f +0000000052 00000 n +0000000207 00000 n +0000000316 00000 n +0000000558 00000 n +0000000657 00000 n +0000000703 00000 n +0000000848 00000 n +trailer << + /Root 1 0 R + /Size 8 + /ID [<31415926535897932384626433832795>] +>> +startxref +883 +%%EOF diff --git a/qpdf/qtest/qpdf/extensions-adbe-force-1.8.out b/qpdf/qtest/qpdf/extensions-adbe-force-1.8.out new file mode 100644 index 00000000..491fdb7e --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-adbe-force-1.8.out @@ -0,0 +1,4 @@ +version: 1.8 +extension level: 0 +null +test 34 done diff --git a/qpdf/qtest/qpdf/extensions-adbe-min-1.3.out b/qpdf/qtest/qpdf/extensions-adbe-min-1.3.out new file mode 100644 index 00000000..4571bf2e --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-adbe-min-1.3.out @@ -0,0 +1,4 @@ +version: 1.7 +extension level: 2 +<< /ADBE << /BaseVersion /1.7 /ExtensionLevel 2 /URL (http://something.adobe.com) >> >> +test 34 done diff --git a/qpdf/qtest/qpdf/extensions-adbe-min-1.6.out b/qpdf/qtest/qpdf/extensions-adbe-min-1.6.out new file mode 100644 index 00000000..4571bf2e --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-adbe-min-1.6.out @@ -0,0 +1,4 @@ +version: 1.7 +extension level: 2 +<< /ADBE << /BaseVersion /1.7 /ExtensionLevel 2 /URL (http://something.adobe.com) >> >> +test 34 done diff --git a/qpdf/qtest/qpdf/extensions-adbe-min-1.7.1.out b/qpdf/qtest/qpdf/extensions-adbe-min-1.7.1.out new file mode 100644 index 00000000..4571bf2e --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-adbe-min-1.7.1.out @@ -0,0 +1,4 @@ +version: 1.7 +extension level: 2 +<< /ADBE << /BaseVersion /1.7 /ExtensionLevel 2 /URL (http://something.adobe.com) >> >> +test 34 done diff --git a/qpdf/qtest/qpdf/extensions-adbe-min-1.7.2.out b/qpdf/qtest/qpdf/extensions-adbe-min-1.7.2.out new file mode 100644 index 00000000..4571bf2e --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-adbe-min-1.7.2.out @@ -0,0 +1,4 @@ +version: 1.7 +extension level: 2 +<< /ADBE << /BaseVersion /1.7 /ExtensionLevel 2 /URL (http://something.adobe.com) >> >> +test 34 done diff --git a/qpdf/qtest/qpdf/extensions-adbe-min-1.7.3.out b/qpdf/qtest/qpdf/extensions-adbe-min-1.7.3.out new file mode 100644 index 00000000..76321208 --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-adbe-min-1.7.3.out @@ -0,0 +1,4 @@ +version: 1.7 +extension level: 3 +<< /ADBE << /BaseVersion /1.7 /ExtensionLevel 3 >> >> +test 34 done diff --git a/qpdf/qtest/qpdf/extensions-adbe-min-1.8.0.out b/qpdf/qtest/qpdf/extensions-adbe-min-1.8.0.out new file mode 100644 index 00000000..491fdb7e --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-adbe-min-1.8.0.out @@ -0,0 +1,4 @@ +version: 1.8 +extension level: 0 +null +test 34 done diff --git a/qpdf/qtest/qpdf/extensions-adbe-min-1.8.2.out b/qpdf/qtest/qpdf/extensions-adbe-min-1.8.2.out new file mode 100644 index 00000000..7823a1dd --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-adbe-min-1.8.2.out @@ -0,0 +1,4 @@ +version: 1.8 +extension level: 2 +<< /ADBE << /BaseVersion /1.8 /ExtensionLevel 2 >> >> +test 34 done diff --git a/qpdf/qtest/qpdf/extensions-adbe-min-1.8.5.out b/qpdf/qtest/qpdf/extensions-adbe-min-1.8.5.out new file mode 100644 index 00000000..2d78af7e --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-adbe-min-1.8.5.out @@ -0,0 +1,4 @@ +version: 1.8 +extension level: 5 +<< /ADBE << /BaseVersion /1.8 /ExtensionLevel 5 >> >> +test 34 done diff --git a/qpdf/qtest/qpdf/extensions-adbe-min-1.8.out b/qpdf/qtest/qpdf/extensions-adbe-min-1.8.out new file mode 100644 index 00000000..491fdb7e --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-adbe-min-1.8.out @@ -0,0 +1,4 @@ +version: 1.8 +extension level: 0 +null +test 34 done diff --git a/qpdf/qtest/qpdf/extensions-adbe-other-force-1.3.out b/qpdf/qtest/qpdf/extensions-adbe-other-force-1.3.out new file mode 100644 index 00000000..14467414 --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-adbe-other-force-1.3.out @@ -0,0 +1,4 @@ +version: 1.3 +extension level: 0 +<< /Potato << /BaseVersion /3.14159 /ExtensionLevel 16059 >> >> +test 34 done diff --git a/qpdf/qtest/qpdf/extensions-adbe-other-force-1.6.out b/qpdf/qtest/qpdf/extensions-adbe-other-force-1.6.out new file mode 100644 index 00000000..0cc726a6 --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-adbe-other-force-1.6.out @@ -0,0 +1,4 @@ +version: 1.6 +extension level: 0 +<< /Potato << /BaseVersion /3.14159 /ExtensionLevel 16059 >> >> +test 34 done diff --git a/qpdf/qtest/qpdf/extensions-adbe-other-force-1.7.1.out b/qpdf/qtest/qpdf/extensions-adbe-other-force-1.7.1.out new file mode 100644 index 00000000..a714b145 --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-adbe-other-force-1.7.1.out @@ -0,0 +1,4 @@ +version: 1.7 +extension level: 1 +<< /ADBE << /BaseVersion /1.7 /ExtensionLevel 1 >> /Potato << /BaseVersion /3.14159 /ExtensionLevel 16059 >> >> +test 34 done diff --git a/qpdf/qtest/qpdf/extensions-adbe-other-force-1.7.2.out b/qpdf/qtest/qpdf/extensions-adbe-other-force-1.7.2.out new file mode 100644 index 00000000..ed0bf57c --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-adbe-other-force-1.7.2.out @@ -0,0 +1,4 @@ +version: 1.7 +extension level: 2 +<< /ADBE << /BaseVersion /1.7 /ExtensionLevel 2 >> /Potato << /BaseVersion /3.14159 /ExtensionLevel 16059 >> >> +test 34 done diff --git a/qpdf/qtest/qpdf/extensions-adbe-other-force-1.7.3.out b/qpdf/qtest/qpdf/extensions-adbe-other-force-1.7.3.out new file mode 100644 index 00000000..f13ea01b --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-adbe-other-force-1.7.3.out @@ -0,0 +1,4 @@ +version: 1.7 +extension level: 3 +<< /ADBE << /BaseVersion /1.7 /ExtensionLevel 3 >> /Potato << /BaseVersion /3.14159 /ExtensionLevel 16059 >> >> +test 34 done diff --git a/qpdf/qtest/qpdf/extensions-adbe-other-force-1.8.0.out b/qpdf/qtest/qpdf/extensions-adbe-other-force-1.8.0.out new file mode 100644 index 00000000..d121666e --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-adbe-other-force-1.8.0.out @@ -0,0 +1,4 @@ +version: 1.8 +extension level: 0 +<< /Potato << /BaseVersion /3.14159 /ExtensionLevel 16059 >> >> +test 34 done diff --git a/qpdf/qtest/qpdf/extensions-adbe-other-force-1.8.2.out b/qpdf/qtest/qpdf/extensions-adbe-other-force-1.8.2.out new file mode 100644 index 00000000..00858aaa --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-adbe-other-force-1.8.2.out @@ -0,0 +1,4 @@ +version: 1.8 +extension level: 2 +<< /ADBE << /BaseVersion /1.8 /ExtensionLevel 2 >> /Potato << /BaseVersion /3.14159 /ExtensionLevel 16059 >> >> +test 34 done diff --git a/qpdf/qtest/qpdf/extensions-adbe-other-force-1.8.5.out b/qpdf/qtest/qpdf/extensions-adbe-other-force-1.8.5.out new file mode 100644 index 00000000..dcf87e86 --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-adbe-other-force-1.8.5.out @@ -0,0 +1,4 @@ +version: 1.8 +extension level: 5 +<< /ADBE << /BaseVersion /1.8 /ExtensionLevel 5 >> /Potato << /BaseVersion /3.14159 /ExtensionLevel 16059 >> >> +test 34 done diff --git a/qpdf/qtest/qpdf/extensions-adbe-other-force-1.8.5.pdf b/qpdf/qtest/qpdf/extensions-adbe-other-force-1.8.5.pdf new file mode 100644 index 00000000..39ea71ef Binary files /dev/null and b/qpdf/qtest/qpdf/extensions-adbe-other-force-1.8.5.pdf differ diff --git a/qpdf/qtest/qpdf/extensions-adbe-other-force-1.8.5.qdf b/qpdf/qtest/qpdf/extensions-adbe-other-force-1.8.5.qdf new file mode 100644 index 00000000..5993af1f --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-adbe-other-force-1.8.5.qdf @@ -0,0 +1,108 @@ +%PDF-1.8 +%¿÷¢þ +%QDF-1.0 + +%% Original object ID: 1 0 +1 0 obj +<< + /Extensions << + /ADBE << /BaseVersion /1.8 /ExtensionLevel 5 >> + /Potato << + /BaseVersion /3.14159 + /ExtensionLevel 16059 + >> + >> + /Pages 2 0 R + /Type /Catalog +>> +endobj + +%% Original object ID: 2 0 +2 0 obj +<< + /Count 1 + /Kids [ + 3 0 R + ] + /Type /Pages +>> +endobj + +%% Page 1 +%% Original object ID: 3 0 +3 0 obj +<< + /Contents 4 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 2 0 R + /Resources << + /Font << + /F1 6 0 R + >> + /ProcSet 7 0 R + >> + /Type /Page +>> +endobj + +%% Contents for page 1 +%% Original object ID: 4 0 +4 0 obj +<< + /Length 5 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Potato) Tj +ET +endstream +endobj + +5 0 obj +44 +endobj + +%% Original object ID: 6 0 +6 0 obj +<< + /BaseFont /Helvetica + /Encoding /WinAnsiEncoding + /Name /F1 + /Subtype /Type1 + /Type /Font +>> +endobj + +%% Original object ID: 7 0 +7 0 obj +[ + /PDF + /Text +] +endobj + +xref +0 8 +0000000000 65535 f +0000000052 00000 n +0000000285 00000 n +0000000394 00000 n +0000000636 00000 n +0000000735 00000 n +0000000781 00000 n +0000000926 00000 n +trailer << + /Root 1 0 R + /Size 8 + /ID [<484577389048fa45fc00a1f5b434efa5><31415926535897932384626433832795>] +>> +startxref +961 +%%EOF diff --git a/qpdf/qtest/qpdf/extensions-adbe-other-force-1.8.out b/qpdf/qtest/qpdf/extensions-adbe-other-force-1.8.out new file mode 100644 index 00000000..d121666e --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-adbe-other-force-1.8.out @@ -0,0 +1,4 @@ +version: 1.8 +extension level: 0 +<< /Potato << /BaseVersion /3.14159 /ExtensionLevel 16059 >> >> +test 34 done diff --git a/qpdf/qtest/qpdf/extensions-adbe-other-min-1.3.out b/qpdf/qtest/qpdf/extensions-adbe-other-min-1.3.out new file mode 100644 index 00000000..ed0bf57c --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-adbe-other-min-1.3.out @@ -0,0 +1,4 @@ +version: 1.7 +extension level: 2 +<< /ADBE << /BaseVersion /1.7 /ExtensionLevel 2 >> /Potato << /BaseVersion /3.14159 /ExtensionLevel 16059 >> >> +test 34 done diff --git a/qpdf/qtest/qpdf/extensions-adbe-other-min-1.6.out b/qpdf/qtest/qpdf/extensions-adbe-other-min-1.6.out new file mode 100644 index 00000000..ed0bf57c --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-adbe-other-min-1.6.out @@ -0,0 +1,4 @@ +version: 1.7 +extension level: 2 +<< /ADBE << /BaseVersion /1.7 /ExtensionLevel 2 >> /Potato << /BaseVersion /3.14159 /ExtensionLevel 16059 >> >> +test 34 done diff --git a/qpdf/qtest/qpdf/extensions-adbe-other-min-1.7.1.out b/qpdf/qtest/qpdf/extensions-adbe-other-min-1.7.1.out new file mode 100644 index 00000000..ed0bf57c --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-adbe-other-min-1.7.1.out @@ -0,0 +1,4 @@ +version: 1.7 +extension level: 2 +<< /ADBE << /BaseVersion /1.7 /ExtensionLevel 2 >> /Potato << /BaseVersion /3.14159 /ExtensionLevel 16059 >> >> +test 34 done diff --git a/qpdf/qtest/qpdf/extensions-adbe-other-min-1.7.2.out b/qpdf/qtest/qpdf/extensions-adbe-other-min-1.7.2.out new file mode 100644 index 00000000..ed0bf57c --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-adbe-other-min-1.7.2.out @@ -0,0 +1,4 @@ +version: 1.7 +extension level: 2 +<< /ADBE << /BaseVersion /1.7 /ExtensionLevel 2 >> /Potato << /BaseVersion /3.14159 /ExtensionLevel 16059 >> >> +test 34 done diff --git a/qpdf/qtest/qpdf/extensions-adbe-other-min-1.7.3.out b/qpdf/qtest/qpdf/extensions-adbe-other-min-1.7.3.out new file mode 100644 index 00000000..f13ea01b --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-adbe-other-min-1.7.3.out @@ -0,0 +1,4 @@ +version: 1.7 +extension level: 3 +<< /ADBE << /BaseVersion /1.7 /ExtensionLevel 3 >> /Potato << /BaseVersion /3.14159 /ExtensionLevel 16059 >> >> +test 34 done diff --git a/qpdf/qtest/qpdf/extensions-adbe-other-min-1.8.0.out b/qpdf/qtest/qpdf/extensions-adbe-other-min-1.8.0.out new file mode 100644 index 00000000..d121666e --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-adbe-other-min-1.8.0.out @@ -0,0 +1,4 @@ +version: 1.8 +extension level: 0 +<< /Potato << /BaseVersion /3.14159 /ExtensionLevel 16059 >> >> +test 34 done diff --git a/qpdf/qtest/qpdf/extensions-adbe-other-min-1.8.2.out b/qpdf/qtest/qpdf/extensions-adbe-other-min-1.8.2.out new file mode 100644 index 00000000..00858aaa --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-adbe-other-min-1.8.2.out @@ -0,0 +1,4 @@ +version: 1.8 +extension level: 2 +<< /ADBE << /BaseVersion /1.8 /ExtensionLevel 2 >> /Potato << /BaseVersion /3.14159 /ExtensionLevel 16059 >> >> +test 34 done diff --git a/qpdf/qtest/qpdf/extensions-adbe-other-min-1.8.5.out b/qpdf/qtest/qpdf/extensions-adbe-other-min-1.8.5.out new file mode 100644 index 00000000..dcf87e86 --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-adbe-other-min-1.8.5.out @@ -0,0 +1,4 @@ +version: 1.8 +extension level: 5 +<< /ADBE << /BaseVersion /1.8 /ExtensionLevel 5 >> /Potato << /BaseVersion /3.14159 /ExtensionLevel 16059 >> >> +test 34 done diff --git a/qpdf/qtest/qpdf/extensions-adbe-other-min-1.8.out b/qpdf/qtest/qpdf/extensions-adbe-other-min-1.8.out new file mode 100644 index 00000000..d121666e --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-adbe-other-min-1.8.out @@ -0,0 +1,4 @@ +version: 1.8 +extension level: 0 +<< /Potato << /BaseVersion /3.14159 /ExtensionLevel 16059 >> >> +test 34 done diff --git a/qpdf/qtest/qpdf/extensions-adbe-other.pdf b/qpdf/qtest/qpdf/extensions-adbe-other.pdf new file mode 100644 index 00000000..367f3766 --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-adbe-other.pdf @@ -0,0 +1,104 @@ +%PDF-1.7 +%¿÷¢þ +%QDF-1.0 + +1 0 obj +<< + /Pages 2 0 R + /Type /Catalog + /Extensions << + /ADBE 8 0 R + /Potato << /BaseVersion /3.14159 /ExtensionLevel 16059 >> + >> +>> +endobj + +2 0 obj +<< + /Count 1 + /Kids [ + 3 0 R + ] + /Type /Pages +>> +endobj + +%% Page 1 +3 0 obj +<< + /Contents 4 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 2 0 R + /Resources << + /Font << + /F1 6 0 R + >> + /ProcSet 7 0 R + >> + /Type /Page +>> +endobj + +%% Contents for page 1 +4 0 obj +<< + /Length 5 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Potato) Tj +ET +endstream +endobj + +5 0 obj +44 +endobj + +6 0 obj +<< + /BaseFont /Helvetica + /Encoding /WinAnsiEncoding + /Name /F1 + /Subtype /Type1 + /Type /Font +>> +endobj + +7 0 obj +[ + /PDF + /Text +] +endobj + +8 0 obj +<< /BaseVersion /1.7 /ExtensionLevel 2 >> +endobj + +xref +0 9 +0000000000 65535 f +0000000025 00000 n +0000000179 00000 n +0000000261 00000 n +0000000476 00000 n +0000000575 00000 n +0000000594 00000 n +0000000712 00000 n +0000000747 00000 n +trailer << + /Root 1 0 R + /Size 9 + /ID [<484577389048fa45fc00a1f5b434efa5><484577389048fa45fc00a1f5b434efa5>] +>> +startxref +805 +%%EOF diff --git a/qpdf/qtest/qpdf/extensions-adbe.pdf b/qpdf/qtest/qpdf/extensions-adbe.pdf new file mode 100644 index 00000000..4d13cf7d --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-adbe.pdf @@ -0,0 +1,106 @@ +%PDF-1.7 +%¿÷¢þ +%QDF-1.0 + +1 0 obj +<< + /Pages 2 0 R + /Type /Catalog + /Extensions 8 0 R +>> +endobj + +2 0 obj +<< + /Count 1 + /Kids [ + 3 0 R + ] + /Type /Pages +>> +endobj + +%% Page 1 +3 0 obj +<< + /Contents 4 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 2 0 R + /Resources << + /Font << + /F1 6 0 R + >> + /ProcSet 7 0 R + >> + /Type /Page +>> +endobj + +%% Contents for page 1 +4 0 obj +<< + /Length 5 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Potato) Tj +ET +endstream +endobj + +5 0 obj +44 +endobj + +6 0 obj +<< + /BaseFont /Helvetica + /Encoding /WinAnsiEncoding + /Name /F1 + /Subtype /Type1 + /Type /Font +>> +endobj + +7 0 obj +[ + /PDF + /Text +] +endobj + +8 0 obj +<< /ADBE 9 0 R >> +endobj + +9 0 obj +<< /BaseVersion /1.7 /ExtensionLevel 2 /URL (http://something.adobe.com) >> +endobj + +xref +0 10 +0000000000 65535 f +0000000025 00000 n +0000000099 00000 n +0000000181 00000 n +0000000396 00000 n +0000000495 00000 n +0000000514 00000 n +0000000632 00000 n +0000000667 00000 n +0000000701 00000 n +trailer << + /Root 1 0 R + /Size 10 + /ID [] +>> +startxref +793 +%%EOF diff --git a/qpdf/qtest/qpdf/extensions-none-force-1.3.out b/qpdf/qtest/qpdf/extensions-none-force-1.3.out new file mode 100644 index 00000000..3795c645 --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-none-force-1.3.out @@ -0,0 +1,4 @@ +version: 1.3 +extension level: 0 +null +test 34 done diff --git a/qpdf/qtest/qpdf/extensions-none-force-1.6.out b/qpdf/qtest/qpdf/extensions-none-force-1.6.out new file mode 100644 index 00000000..762063b9 --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-none-force-1.6.out @@ -0,0 +1,4 @@ +version: 1.6 +extension level: 0 +null +test 34 done diff --git a/qpdf/qtest/qpdf/extensions-none-force-1.7.1.out b/qpdf/qtest/qpdf/extensions-none-force-1.7.1.out new file mode 100644 index 00000000..96168639 --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-none-force-1.7.1.out @@ -0,0 +1,4 @@ +version: 1.7 +extension level: 1 +<< /ADBE << /BaseVersion /1.7 /ExtensionLevel 1 >> >> +test 34 done diff --git a/qpdf/qtest/qpdf/extensions-none-force-1.7.2.out b/qpdf/qtest/qpdf/extensions-none-force-1.7.2.out new file mode 100644 index 00000000..234701c6 --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-none-force-1.7.2.out @@ -0,0 +1,4 @@ +version: 1.7 +extension level: 2 +<< /ADBE << /BaseVersion /1.7 /ExtensionLevel 2 >> >> +test 34 done diff --git a/qpdf/qtest/qpdf/extensions-none-force-1.7.3.out b/qpdf/qtest/qpdf/extensions-none-force-1.7.3.out new file mode 100644 index 00000000..76321208 --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-none-force-1.7.3.out @@ -0,0 +1,4 @@ +version: 1.7 +extension level: 3 +<< /ADBE << /BaseVersion /1.7 /ExtensionLevel 3 >> >> +test 34 done diff --git a/qpdf/qtest/qpdf/extensions-none-force-1.8.0.out b/qpdf/qtest/qpdf/extensions-none-force-1.8.0.out new file mode 100644 index 00000000..491fdb7e --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-none-force-1.8.0.out @@ -0,0 +1,4 @@ +version: 1.8 +extension level: 0 +null +test 34 done diff --git a/qpdf/qtest/qpdf/extensions-none-force-1.8.2.out b/qpdf/qtest/qpdf/extensions-none-force-1.8.2.out new file mode 100644 index 00000000..7823a1dd --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-none-force-1.8.2.out @@ -0,0 +1,4 @@ +version: 1.8 +extension level: 2 +<< /ADBE << /BaseVersion /1.8 /ExtensionLevel 2 >> >> +test 34 done diff --git a/qpdf/qtest/qpdf/extensions-none-force-1.8.5.out b/qpdf/qtest/qpdf/extensions-none-force-1.8.5.out new file mode 100644 index 00000000..2d78af7e --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-none-force-1.8.5.out @@ -0,0 +1,4 @@ +version: 1.8 +extension level: 5 +<< /ADBE << /BaseVersion /1.8 /ExtensionLevel 5 >> >> +test 34 done diff --git a/qpdf/qtest/qpdf/extensions-none-force-1.8.5.pdf b/qpdf/qtest/qpdf/extensions-none-force-1.8.5.pdf new file mode 100644 index 00000000..52f5623e Binary files /dev/null and b/qpdf/qtest/qpdf/extensions-none-force-1.8.5.pdf differ diff --git a/qpdf/qtest/qpdf/extensions-none-force-1.8.5.qdf b/qpdf/qtest/qpdf/extensions-none-force-1.8.5.qdf new file mode 100644 index 00000000..c6f9a1f6 --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-none-force-1.8.5.qdf @@ -0,0 +1,102 @@ +%PDF-1.8 +%¿÷¢þ +%QDF-1.0 + +%% Original object ID: 1 0 +1 0 obj +<< + /Extensions << /ADBE << /BaseVersion /1.8 /ExtensionLevel 5 >> >> + /Pages 2 0 R + /Type /Catalog +>> +endobj + +%% Original object ID: 2 0 +2 0 obj +<< + /Count 1 + /Kids [ + 3 0 R + ] + /Type /Pages +>> +endobj + +%% Page 1 +%% Original object ID: 3 0 +3 0 obj +<< + /Contents 4 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 2 0 R + /Resources << + /Font << + /F1 6 0 R + >> + /ProcSet 7 0 R + >> + /Type /Page +>> +endobj + +%% Contents for page 1 +%% Original object ID: 4 0 +4 0 obj +<< + /Length 5 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Potato) Tj +ET +endstream +endobj + +5 0 obj +44 +endobj + +%% Original object ID: 6 0 +6 0 obj +<< + /BaseFont /Helvetica + /Encoding /WinAnsiEncoding + /Name /F1 + /Subtype /Type1 + /Type /Font +>> +endobj + +%% Original object ID: 5 0 +7 0 obj +[ + /PDF + /Text +] +endobj + +xref +0 8 +0000000000 65535 f +0000000052 00000 n +0000000201 00000 n +0000000310 00000 n +0000000552 00000 n +0000000651 00000 n +0000000697 00000 n +0000000842 00000 n +trailer << + /Root 1 0 R + /Size 8 + /ID [<31415926535897932384626433832795><31415926535897932384626433832795>] +>> +startxref +877 +%%EOF diff --git a/qpdf/qtest/qpdf/extensions-none-force-1.8.out b/qpdf/qtest/qpdf/extensions-none-force-1.8.out new file mode 100644 index 00000000..491fdb7e --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-none-force-1.8.out @@ -0,0 +1,4 @@ +version: 1.8 +extension level: 0 +null +test 34 done diff --git a/qpdf/qtest/qpdf/extensions-none-min-1.3.out b/qpdf/qtest/qpdf/extensions-none-min-1.3.out new file mode 100644 index 00000000..3795c645 --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-none-min-1.3.out @@ -0,0 +1,4 @@ +version: 1.3 +extension level: 0 +null +test 34 done diff --git a/qpdf/qtest/qpdf/extensions-none-min-1.6.out b/qpdf/qtest/qpdf/extensions-none-min-1.6.out new file mode 100644 index 00000000..762063b9 --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-none-min-1.6.out @@ -0,0 +1,4 @@ +version: 1.6 +extension level: 0 +null +test 34 done diff --git a/qpdf/qtest/qpdf/extensions-none-min-1.7.1.out b/qpdf/qtest/qpdf/extensions-none-min-1.7.1.out new file mode 100644 index 00000000..96168639 --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-none-min-1.7.1.out @@ -0,0 +1,4 @@ +version: 1.7 +extension level: 1 +<< /ADBE << /BaseVersion /1.7 /ExtensionLevel 1 >> >> +test 34 done diff --git a/qpdf/qtest/qpdf/extensions-none-min-1.7.2.out b/qpdf/qtest/qpdf/extensions-none-min-1.7.2.out new file mode 100644 index 00000000..234701c6 --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-none-min-1.7.2.out @@ -0,0 +1,4 @@ +version: 1.7 +extension level: 2 +<< /ADBE << /BaseVersion /1.7 /ExtensionLevel 2 >> >> +test 34 done diff --git a/qpdf/qtest/qpdf/extensions-none-min-1.7.3.out b/qpdf/qtest/qpdf/extensions-none-min-1.7.3.out new file mode 100644 index 00000000..76321208 --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-none-min-1.7.3.out @@ -0,0 +1,4 @@ +version: 1.7 +extension level: 3 +<< /ADBE << /BaseVersion /1.7 /ExtensionLevel 3 >> >> +test 34 done diff --git a/qpdf/qtest/qpdf/extensions-none-min-1.8.0.out b/qpdf/qtest/qpdf/extensions-none-min-1.8.0.out new file mode 100644 index 00000000..491fdb7e --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-none-min-1.8.0.out @@ -0,0 +1,4 @@ +version: 1.8 +extension level: 0 +null +test 34 done diff --git a/qpdf/qtest/qpdf/extensions-none-min-1.8.2.out b/qpdf/qtest/qpdf/extensions-none-min-1.8.2.out new file mode 100644 index 00000000..7823a1dd --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-none-min-1.8.2.out @@ -0,0 +1,4 @@ +version: 1.8 +extension level: 2 +<< /ADBE << /BaseVersion /1.8 /ExtensionLevel 2 >> >> +test 34 done diff --git a/qpdf/qtest/qpdf/extensions-none-min-1.8.5.out b/qpdf/qtest/qpdf/extensions-none-min-1.8.5.out new file mode 100644 index 00000000..2d78af7e --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-none-min-1.8.5.out @@ -0,0 +1,4 @@ +version: 1.8 +extension level: 5 +<< /ADBE << /BaseVersion /1.8 /ExtensionLevel 5 >> >> +test 34 done diff --git a/qpdf/qtest/qpdf/extensions-none-min-1.8.out b/qpdf/qtest/qpdf/extensions-none-min-1.8.out new file mode 100644 index 00000000..491fdb7e --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-none-min-1.8.out @@ -0,0 +1,4 @@ +version: 1.8 +extension level: 0 +null +test 34 done diff --git a/qpdf/qtest/qpdf/extensions-other-force-1.3.out b/qpdf/qtest/qpdf/extensions-other-force-1.3.out new file mode 100644 index 00000000..14467414 --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-other-force-1.3.out @@ -0,0 +1,4 @@ +version: 1.3 +extension level: 0 +<< /Potato << /BaseVersion /3.14159 /ExtensionLevel 16059 >> >> +test 34 done diff --git a/qpdf/qtest/qpdf/extensions-other-force-1.6.out b/qpdf/qtest/qpdf/extensions-other-force-1.6.out new file mode 100644 index 00000000..0cc726a6 --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-other-force-1.6.out @@ -0,0 +1,4 @@ +version: 1.6 +extension level: 0 +<< /Potato << /BaseVersion /3.14159 /ExtensionLevel 16059 >> >> +test 34 done diff --git a/qpdf/qtest/qpdf/extensions-other-force-1.7.1.out b/qpdf/qtest/qpdf/extensions-other-force-1.7.1.out new file mode 100644 index 00000000..a714b145 --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-other-force-1.7.1.out @@ -0,0 +1,4 @@ +version: 1.7 +extension level: 1 +<< /ADBE << /BaseVersion /1.7 /ExtensionLevel 1 >> /Potato << /BaseVersion /3.14159 /ExtensionLevel 16059 >> >> +test 34 done diff --git a/qpdf/qtest/qpdf/extensions-other-force-1.7.2.out b/qpdf/qtest/qpdf/extensions-other-force-1.7.2.out new file mode 100644 index 00000000..ed0bf57c --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-other-force-1.7.2.out @@ -0,0 +1,4 @@ +version: 1.7 +extension level: 2 +<< /ADBE << /BaseVersion /1.7 /ExtensionLevel 2 >> /Potato << /BaseVersion /3.14159 /ExtensionLevel 16059 >> >> +test 34 done diff --git a/qpdf/qtest/qpdf/extensions-other-force-1.7.3.out b/qpdf/qtest/qpdf/extensions-other-force-1.7.3.out new file mode 100644 index 00000000..f13ea01b --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-other-force-1.7.3.out @@ -0,0 +1,4 @@ +version: 1.7 +extension level: 3 +<< /ADBE << /BaseVersion /1.7 /ExtensionLevel 3 >> /Potato << /BaseVersion /3.14159 /ExtensionLevel 16059 >> >> +test 34 done diff --git a/qpdf/qtest/qpdf/extensions-other-force-1.8.0.out b/qpdf/qtest/qpdf/extensions-other-force-1.8.0.out new file mode 100644 index 00000000..d121666e --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-other-force-1.8.0.out @@ -0,0 +1,4 @@ +version: 1.8 +extension level: 0 +<< /Potato << /BaseVersion /3.14159 /ExtensionLevel 16059 >> >> +test 34 done diff --git a/qpdf/qtest/qpdf/extensions-other-force-1.8.2.out b/qpdf/qtest/qpdf/extensions-other-force-1.8.2.out new file mode 100644 index 00000000..00858aaa --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-other-force-1.8.2.out @@ -0,0 +1,4 @@ +version: 1.8 +extension level: 2 +<< /ADBE << /BaseVersion /1.8 /ExtensionLevel 2 >> /Potato << /BaseVersion /3.14159 /ExtensionLevel 16059 >> >> +test 34 done diff --git a/qpdf/qtest/qpdf/extensions-other-force-1.8.5.out b/qpdf/qtest/qpdf/extensions-other-force-1.8.5.out new file mode 100644 index 00000000..dcf87e86 --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-other-force-1.8.5.out @@ -0,0 +1,4 @@ +version: 1.8 +extension level: 5 +<< /ADBE << /BaseVersion /1.8 /ExtensionLevel 5 >> /Potato << /BaseVersion /3.14159 /ExtensionLevel 16059 >> >> +test 34 done diff --git a/qpdf/qtest/qpdf/extensions-other-force-1.8.5.pdf b/qpdf/qtest/qpdf/extensions-other-force-1.8.5.pdf new file mode 100644 index 00000000..8bf4fe06 Binary files /dev/null and b/qpdf/qtest/qpdf/extensions-other-force-1.8.5.pdf differ diff --git a/qpdf/qtest/qpdf/extensions-other-force-1.8.5.qdf b/qpdf/qtest/qpdf/extensions-other-force-1.8.5.qdf new file mode 100644 index 00000000..3c596f7d --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-other-force-1.8.5.qdf @@ -0,0 +1,108 @@ +%PDF-1.8 +%¿÷¢þ +%QDF-1.0 + +%% Original object ID: 1 0 +1 0 obj +<< + /Extensions << + /ADBE << /BaseVersion /1.8 /ExtensionLevel 5 >> + /Potato << + /BaseVersion /3.14159 + /ExtensionLevel 16059 + >> + >> + /Pages 2 0 R + /Type /Catalog +>> +endobj + +%% Original object ID: 2 0 +2 0 obj +<< + /Count 1 + /Kids [ + 3 0 R + ] + /Type /Pages +>> +endobj + +%% Page 1 +%% Original object ID: 3 0 +3 0 obj +<< + /Contents 4 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 2 0 R + /Resources << + /Font << + /F1 6 0 R + >> + /ProcSet 7 0 R + >> + /Type /Page +>> +endobj + +%% Contents for page 1 +%% Original object ID: 4 0 +4 0 obj +<< + /Length 5 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Potato) Tj +ET +endstream +endobj + +5 0 obj +44 +endobj + +%% Original object ID: 6 0 +6 0 obj +<< + /BaseFont /Helvetica + /Encoding /WinAnsiEncoding + /Name /F1 + /Subtype /Type1 + /Type /Font +>> +endobj + +%% Original object ID: 7 0 +7 0 obj +[ + /PDF + /Text +] +endobj + +xref +0 8 +0000000000 65535 f +0000000052 00000 n +0000000285 00000 n +0000000394 00000 n +0000000636 00000 n +0000000735 00000 n +0000000781 00000 n +0000000926 00000 n +trailer << + /Root 1 0 R + /Size 8 + /ID [<369e89600ee1a6c4c7e73533610180c2><31415926535897932384626433832795>] +>> +startxref +961 +%%EOF diff --git a/qpdf/qtest/qpdf/extensions-other-force-1.8.out b/qpdf/qtest/qpdf/extensions-other-force-1.8.out new file mode 100644 index 00000000..d121666e --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-other-force-1.8.out @@ -0,0 +1,4 @@ +version: 1.8 +extension level: 0 +<< /Potato << /BaseVersion /3.14159 /ExtensionLevel 16059 >> >> +test 34 done diff --git a/qpdf/qtest/qpdf/extensions-other-min-1.3.out b/qpdf/qtest/qpdf/extensions-other-min-1.3.out new file mode 100644 index 00000000..0f576775 --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-other-min-1.3.out @@ -0,0 +1,4 @@ +version: 1.5 +extension level: 0 +<< /Potato << /BaseVersion /3.14159 /ExtensionLevel 16059 >> >> +test 34 done diff --git a/qpdf/qtest/qpdf/extensions-other-min-1.6.out b/qpdf/qtest/qpdf/extensions-other-min-1.6.out new file mode 100644 index 00000000..0cc726a6 --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-other-min-1.6.out @@ -0,0 +1,4 @@ +version: 1.6 +extension level: 0 +<< /Potato << /BaseVersion /3.14159 /ExtensionLevel 16059 >> >> +test 34 done diff --git a/qpdf/qtest/qpdf/extensions-other-min-1.7.1.out b/qpdf/qtest/qpdf/extensions-other-min-1.7.1.out new file mode 100644 index 00000000..a714b145 --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-other-min-1.7.1.out @@ -0,0 +1,4 @@ +version: 1.7 +extension level: 1 +<< /ADBE << /BaseVersion /1.7 /ExtensionLevel 1 >> /Potato << /BaseVersion /3.14159 /ExtensionLevel 16059 >> >> +test 34 done diff --git a/qpdf/qtest/qpdf/extensions-other-min-1.7.2.out b/qpdf/qtest/qpdf/extensions-other-min-1.7.2.out new file mode 100644 index 00000000..ed0bf57c --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-other-min-1.7.2.out @@ -0,0 +1,4 @@ +version: 1.7 +extension level: 2 +<< /ADBE << /BaseVersion /1.7 /ExtensionLevel 2 >> /Potato << /BaseVersion /3.14159 /ExtensionLevel 16059 >> >> +test 34 done diff --git a/qpdf/qtest/qpdf/extensions-other-min-1.7.3.out b/qpdf/qtest/qpdf/extensions-other-min-1.7.3.out new file mode 100644 index 00000000..f13ea01b --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-other-min-1.7.3.out @@ -0,0 +1,4 @@ +version: 1.7 +extension level: 3 +<< /ADBE << /BaseVersion /1.7 /ExtensionLevel 3 >> /Potato << /BaseVersion /3.14159 /ExtensionLevel 16059 >> >> +test 34 done diff --git a/qpdf/qtest/qpdf/extensions-other-min-1.8.0.out b/qpdf/qtest/qpdf/extensions-other-min-1.8.0.out new file mode 100644 index 00000000..d121666e --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-other-min-1.8.0.out @@ -0,0 +1,4 @@ +version: 1.8 +extension level: 0 +<< /Potato << /BaseVersion /3.14159 /ExtensionLevel 16059 >> >> +test 34 done diff --git a/qpdf/qtest/qpdf/extensions-other-min-1.8.2.out b/qpdf/qtest/qpdf/extensions-other-min-1.8.2.out new file mode 100644 index 00000000..00858aaa --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-other-min-1.8.2.out @@ -0,0 +1,4 @@ +version: 1.8 +extension level: 2 +<< /ADBE << /BaseVersion /1.8 /ExtensionLevel 2 >> /Potato << /BaseVersion /3.14159 /ExtensionLevel 16059 >> >> +test 34 done diff --git a/qpdf/qtest/qpdf/extensions-other-min-1.8.5.out b/qpdf/qtest/qpdf/extensions-other-min-1.8.5.out new file mode 100644 index 00000000..dcf87e86 --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-other-min-1.8.5.out @@ -0,0 +1,4 @@ +version: 1.8 +extension level: 5 +<< /ADBE << /BaseVersion /1.8 /ExtensionLevel 5 >> /Potato << /BaseVersion /3.14159 /ExtensionLevel 16059 >> >> +test 34 done diff --git a/qpdf/qtest/qpdf/extensions-other-min-1.8.out b/qpdf/qtest/qpdf/extensions-other-min-1.8.out new file mode 100644 index 00000000..d121666e --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-other-min-1.8.out @@ -0,0 +1,4 @@ +version: 1.8 +extension level: 0 +<< /Potato << /BaseVersion /3.14159 /ExtensionLevel 16059 >> >> +test 34 done diff --git a/qpdf/qtest/qpdf/extensions-other.pdf b/qpdf/qtest/qpdf/extensions-other.pdf new file mode 100644 index 00000000..e8639813 --- /dev/null +++ b/qpdf/qtest/qpdf/extensions-other.pdf @@ -0,0 +1,98 @@ +%PDF-1.5 +%¿÷¢þ +%QDF-1.0 + +1 0 obj +<< + /Pages 2 0 R + /Type /Catalog + /Extensions << + /Potato << /BaseVersion /3.14159 /ExtensionLevel 16059 >> + >> +>> +endobj + +2 0 obj +<< + /Count 1 + /Kids [ + 3 0 R + ] + /Type /Pages +>> +endobj + +%% Page 1 +3 0 obj +<< + /Contents 4 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 2 0 R + /Resources << + /Font << + /F1 6 0 R + >> + /ProcSet 7 0 R + >> + /Type /Page +>> +endobj + +%% Contents for page 1 +4 0 obj +<< + /Length 5 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Potato) Tj +ET +endstream +endobj + +5 0 obj +44 +endobj + +6 0 obj +<< + /BaseFont /Helvetica + /Encoding /WinAnsiEncoding + /Name /F1 + /Subtype /Type1 + /Type /Font +>> +endobj + +7 0 obj +[ + /PDF + /Text +] +endobj + +xref +0 8 +0000000000 65535 f +0000000025 00000 n +0000000163 00000 n +0000000245 00000 n +0000000460 00000 n +0000000559 00000 n +0000000578 00000 n +0000000696 00000 n +trailer << + /Root 1 0 R + /Size 8 + /ID [<369e89600ee1a6c4c7e73533610180c2><369e89600ee1a6c4c7e73533610180c2>] +>> +startxref +731 +%%EOF diff --git a/qpdf/qtest/qpdf/obj0-check.out b/qpdf/qtest/qpdf/obj0-check.out index f0a71b66..1b4bcf46 100644 --- a/qpdf/qtest/qpdf/obj0-check.out +++ b/qpdf/qtest/qpdf/obj0-check.out @@ -1,7 +1,7 @@ checking obj0.pdf -PDF Version: 1.3 -File is not encrypted -File is not linearized WARNING: obj0.pdf: file is damaged WARNING: obj0.pdf (object 1 0, file position 77): expected n n obj WARNING: obj0.pdf: Attempting to reconstruct cross-reference table +PDF Version: 1.3 +File is not encrypted +File is not linearized diff --git a/qpdf/test_driver.cc b/qpdf/test_driver.cc index 2c729987..f8294889 100644 --- a/qpdf/test_driver.cc +++ b/qpdf/test_driver.cc @@ -1126,6 +1126,13 @@ void runtest(int n, char const* filename1, char const* filename2) fwrite(b->getBuffer(), b->getSize(), 1, f); fclose(f); } + else if (n == 34) + { + // Look at Extensions dictionary + std::cout << "version: " << pdf.getPDFVersion() << std::endl + << "extension level: " << pdf.getExtensionLevel() << std::endl + << pdf.getRoot().getKey("/Extensions").unparse() << std::endl; + } else { throw std::runtime_error(std::string("invalid test ") + -- cgit v1.2.3-70-g09d2