mirror of
https://github.com/qpdf/qpdf.git
synced 2025-01-02 22:50:20 +00:00
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.
This commit is contained in:
parent
eae8370cd9
commit
16051788ed
@ -1,5 +1,11 @@
|
|||||||
2013-06-14 Jay Berkenbilt <ejb@ql.org>
|
2013-06-14 Jay Berkenbilt <ejb@ql.org>
|
||||||
|
|
||||||
|
* Detect and correct /Outlines dictionary being a direct object
|
||||||
|
when linearizing files. This is not allowed by the spec but has
|
||||||
|
been seen in the wild. Prior to this change, such a file would
|
||||||
|
cause an internal error in the linearization code, which assumed
|
||||||
|
/Outlines was indirect.
|
||||||
|
|
||||||
* Add /Length key to crypt filter dictionary for encrypted files.
|
* Add /Length key to crypt filter dictionary for encrypted files.
|
||||||
This key is optional, but some version of MacOS reportedly fail to
|
This key is optional, but some version of MacOS reportedly fail to
|
||||||
open encrypted PDF files without this key.
|
open encrypted PDF files without this key.
|
||||||
|
@ -958,6 +958,15 @@ QPDF::checkHOutlines(std::list<std::string>& warnings)
|
|||||||
{
|
{
|
||||||
// Check length and offset. Acrobat gets these wrong.
|
// Check length and offset. Acrobat gets these wrong.
|
||||||
QPDFObjectHandle outlines = getRoot().getKey("/Outlines");
|
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());
|
QPDFObjGen og(outlines.getObjGen());
|
||||||
assert(this->xref_table.count(og) > 0);
|
assert(this->xref_table.count(og) > 0);
|
||||||
int offset = getLinearizationOffset(og);
|
int offset = getLinearizationOffset(og);
|
||||||
|
@ -68,6 +68,20 @@ QPDF::optimize(std::map<int, int> const& object_stream_data,
|
|||||||
return;
|
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
|
// Traverse pages tree pushing all inherited resources down to the
|
||||||
// page level. This also initializes this->all_pages.
|
// page level. This also initializes this->all_pages.
|
||||||
pushInheritedAttributesToPage(allow_changes, false);
|
pushInheritedAttributesToPage(allow_changes, false);
|
||||||
@ -97,7 +111,6 @@ QPDF::optimize(std::map<int, int> const& object_stream_data,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QPDFObjectHandle root = getRoot();
|
|
||||||
keys = root.getKeys();
|
keys = root.getKeys();
|
||||||
for (std::set<std::string>::iterator iter = keys.begin();
|
for (std::set<std::string>::iterator iter = keys.begin();
|
||||||
iter != keys.end(); ++iter)
|
iter != keys.end(); ++iter)
|
||||||
|
@ -263,3 +263,4 @@ QPDFObjectHandle EOF in inline image 0
|
|||||||
QPDFObjectHandle inline image token 0
|
QPDFObjectHandle inline image token 0
|
||||||
QPDF not caching overridden objstm object 0
|
QPDF not caching overridden objstm object 0
|
||||||
QPDFWriter original obj non-zero gen 0
|
QPDFWriter original obj non-zero gen 0
|
||||||
|
QPDF_optimization indirect outlines 0
|
||||||
|
@ -1192,6 +1192,7 @@ my @to_linearize =
|
|||||||
'object-stream', # contains object streams
|
'object-stream', # contains object streams
|
||||||
'hybrid-xref', # contains both xref tables and streams
|
'hybrid-xref', # contains both xref tables and streams
|
||||||
'gen1', # has objects with generation > 0
|
'gen1', # has objects with generation > 0
|
||||||
|
'direct-outlines', # /Outlines is a direct object
|
||||||
@linearized_files, # we should be able to relinearize
|
@linearized_files, # we should be able to relinearize
|
||||||
);
|
);
|
||||||
|
|
||||||
|
1503
qpdf/qtest/qpdf/direct-outlines.pdf
Normal file
1503
qpdf/qtest/qpdf/direct-outlines.pdf
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user