diff options
author | Jay Berkenbilt <ejb@ql.org> | 2020-02-22 17:00:38 +0100 |
---|---|---|
committer | Jay Berkenbilt <ejb@ql.org> | 2020-02-22 17:10:31 +0100 |
commit | bb3137296d4070e268690e8233e9d3eb2d64c652 (patch) | |
tree | dd6fc652f976d41d64c14e0e3bd29c1b85da075d /libqpdf | |
parent | 6d2b4d8f81b1baf0b26af30e275a84ed5d00629a (diff) | |
download | qpdf-bb3137296d4070e268690e8233e9d3eb2d64c652.tar.zst |
Handle root /Pages pointing to other than page tree root (fixes #398)
Diffstat (limited to 'libqpdf')
-rw-r--r-- | libqpdf/QPDF_pages.cc | 32 |
1 files changed, 30 insertions, 2 deletions
diff --git a/libqpdf/QPDF_pages.cc b/libqpdf/QPDF_pages.cc index 6435d91e..931ee12b 100644 --- a/libqpdf/QPDF_pages.cc +++ b/libqpdf/QPDF_pages.cc @@ -49,8 +49,36 @@ QPDF::getAllPages() { std::set<QPDFObjGen> visited; std::set<QPDFObjGen> seen; - getAllPagesInternal(getRoot().getKey("/Pages"), this->m->all_pages, - visited, seen); + QPDFObjectHandle pages = getRoot().getKey("/Pages"); + bool warned = false; + bool changed_pages = false; + while (pages.isDictionary() && pages.hasKey("/Parent")) + { + if (seen.count(pages.getObjGen())) + { + // loop -- will be detected again and reported later + break; + } + // Files have been found in the wild where /Pages in the + // catalog points to the first page. Try to work around + // this and similar cases with this heuristic. + if (! warned) + { + getRoot().warnIfPossible( + "document page tree root (root -> /Pages) doesn't point" + " to the root of the page tree; attempting to correct"); + warned = true; + } + seen.insert(pages.getObjGen()); + changed_pages = true; + pages = pages.getKey("/Parent"); + } + if (changed_pages) + { + getRoot().replaceKey("/Pages", pages); + } + seen.clear(); + getAllPagesInternal(pages, this->m->all_pages, visited, seen); } return this->m->all_pages; } |