From 16051788ed6a8209aadff619b586eac86543b4f9 Mon Sep 17 00:00:00 2001 From: Jay Berkenbilt Date: Fri, 14 Jun 2013 21:35:10 -0400 Subject: 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. --- libqpdf/QPDF_linearization.cc | 9 +++++++++ libqpdf/QPDF_optimization.cc | 15 ++++++++++++++- 2 files changed, 23 insertions(+), 1 deletion(-) (limited to 'libqpdf') 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& 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 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 const& object_stream_data, } } - QPDFObjectHandle root = getRoot(); keys = root.getKeys(); for (std::set::iterator iter = keys.begin(); iter != keys.end(); ++iter) -- cgit v1.2.3-54-g00ecf