diff options
author | Jay Berkenbilt <ejb@ql.org> | 2013-06-15 03:35:10 +0200 |
---|---|---|
committer | Jay Berkenbilt <ejb@ql.org> | 2013-06-15 03:36:04 +0200 |
commit | 16051788ed6a8209aadff619b586eac86543b4f9 (patch) | |
tree | 6262f0eb4d40e56f4d2076da885a57fea96d14aa /libqpdf | |
parent | eae8370cd9c4e6ac748931a425721303561bd6ac (diff) | |
download | qpdf-16051788ed6a8209aadff619b586eac86543b4f9.tar.zst |
Handle /Outlines dictionary being a direct object
Even though this case is not valid according to the spec, it has been
seen, and caused an internal error.
Diffstat (limited to 'libqpdf')
-rw-r--r-- | libqpdf/QPDF_linearization.cc | 9 | ||||
-rw-r--r-- | libqpdf/QPDF_optimization.cc | 15 |
2 files changed, 23 insertions, 1 deletions
diff --git a/libqpdf/QPDF_linearization.cc b/libqpdf/QPDF_linearization.cc index 4b1f5c09..2c4fefc0 100644 --- a/libqpdf/QPDF_linearization.cc +++ b/libqpdf/QPDF_linearization.cc @@ -958,6 +958,15 @@ QPDF::checkHOutlines(std::list<std::string>& warnings) { // Check length and offset. Acrobat gets these wrong. QPDFObjectHandle outlines = getRoot().getKey("/Outlines"); + if (! outlines.isIndirect()) + { + // This case is not exercised in test suite since not + // permitted by the spec, but if this does occur, the + // code below would fail. + warnings.push_back( + "/Outlines key of root dictionary is not indirect"); + return; + } QPDFObjGen og(outlines.getObjGen()); assert(this->xref_table.count(og) > 0); int offset = getLinearizationOffset(og); diff --git a/libqpdf/QPDF_optimization.cc b/libqpdf/QPDF_optimization.cc index 0286fdb9..35663c45 100644 --- a/libqpdf/QPDF_optimization.cc +++ b/libqpdf/QPDF_optimization.cc @@ -68,6 +68,20 @@ QPDF::optimize(std::map<int, int> const& object_stream_data, return; } + // The PDF specification indicates that /Outlines is supposed to + // be an indirect reference. Force it to be so if it exists and + // is direct. (This has been seen in the wild.) + QPDFObjectHandle root = getRoot(); + if (root.getKey("/Outlines").isDictionary()) + { + QPDFObjectHandle outlines = root.getKey("/Outlines"); + if (! outlines.isIndirect()) + { + QTC::TC("qpdf", "QPDF_optimization indirect outlines"); + root.replaceKey("/Outlines", makeIndirectObject(outlines)); + } + } + // Traverse pages tree pushing all inherited resources down to the // page level. This also initializes this->all_pages. pushInheritedAttributesToPage(allow_changes, false); @@ -97,7 +111,6 @@ QPDF::optimize(std::map<int, int> const& object_stream_data, } } - QPDFObjectHandle root = getRoot(); keys = root.getKeys(); for (std::set<std::string>::iterator iter = keys.begin(); iter != keys.end(); ++iter) |