From bb3137296d4070e268690e8233e9d3eb2d64c652 Mon Sep 17 00:00:00 2001 From: Jay Berkenbilt Date: Sat, 22 Feb 2020 11:00:38 -0500 Subject: Handle root /Pages pointing to other than page tree root (fixes #398) --- libqpdf/QPDF_pages.cc | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) (limited to 'libqpdf') 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 visited; std::set 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; } -- cgit v1.2.3-54-g00ecf