aboutsummaryrefslogtreecommitdiffstats
path: root/libqpdf/QPDF_pages.cc
diff options
context:
space:
mode:
authorJay Berkenbilt <ejb@ql.org>2020-02-22 17:00:38 +0100
committerJay Berkenbilt <ejb@ql.org>2020-02-22 17:10:31 +0100
commitbb3137296d4070e268690e8233e9d3eb2d64c652 (patch)
treedd6fc652f976d41d64c14e0e3bd29c1b85da075d /libqpdf/QPDF_pages.cc
parent6d2b4d8f81b1baf0b26af30e275a84ed5d00629a (diff)
downloadqpdf-bb3137296d4070e268690e8233e9d3eb2d64c652.tar.zst
Handle root /Pages pointing to other than page tree root (fixes #398)
Diffstat (limited to 'libqpdf/QPDF_pages.cc')
-rw-r--r--libqpdf/QPDF_pages.cc32
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;
}