Commit 7f2d76b78d5bf7331f99039804c01320673bde13

Authored by m-holger
1 parent 01353e11

Remove non-dictionary objects from pages tree

include/qpdf/QPDF.hh
@@ -1515,6 +1515,7 @@ class QPDF @@ -1515,6 +1515,7 @@ class QPDF
1515 std::set<QPDFObjGen> resolving; 1515 std::set<QPDFObjGen> resolving;
1516 QPDFObjectHandle trailer; 1516 QPDFObjectHandle trailer;
1517 std::vector<QPDFObjectHandle> all_pages; 1517 std::vector<QPDFObjectHandle> all_pages;
  1518 + bool invalid_page_found{false};
1518 std::map<QPDFObjGen, int> pageobj_to_pages_pos; 1519 std::map<QPDFObjGen, int> pageobj_to_pages_pos;
1519 bool pushed_inherited_attributes_to_pages{false}; 1520 bool pushed_inherited_attributes_to_pages{false};
1520 bool ever_pushed_inherited_attributes_to_pages{false}; 1521 bool ever_pushed_inherited_attributes_to_pages{false};
libqpdf/QPDF_pages.cc
@@ -40,7 +40,7 @@ std::vector&lt;QPDFObjectHandle&gt; const&amp; @@ -40,7 +40,7 @@ std::vector&lt;QPDFObjectHandle&gt; const&amp;
40 QPDF::getAllPages() 40 QPDF::getAllPages()
41 { 41 {
42 // Note that pushInheritedAttributesToPage may also be used to initialize m->all_pages. 42 // Note that pushInheritedAttributesToPage may also be used to initialize m->all_pages.
43 - if (m->all_pages.empty()) { 43 + if (m->all_pages.empty() && !m->invalid_page_found) {
44 m->ever_called_get_all_pages = true; 44 m->ever_called_get_all_pages = true;
45 QPDFObjGen::set visited; 45 QPDFObjGen::set visited;
46 QPDFObjGen::set seen; 46 QPDFObjGen::set seen;
@@ -70,6 +70,10 @@ QPDF::getAllPages() @@ -70,6 +70,10 @@ QPDF::getAllPages()
70 // Ensure we actually found a /Pages object. 70 // Ensure we actually found a /Pages object.
71 getAllPagesInternal(pages, visited, seen, false); 71 getAllPagesInternal(pages, visited, seen, false);
72 } 72 }
  73 + if (m->invalid_page_found) {
  74 + flattenPagesTree();
  75 + m->invalid_page_found = false;
  76 + }
73 } 77 }
74 return m->all_pages; 78 return m->all_pages;
75 } 79 }
@@ -100,6 +104,7 @@ QPDF::getAllPagesInternal( @@ -100,6 +104,7 @@ QPDF::getAllPagesInternal(
100 auto kid = kids.getArrayItem(i); 104 auto kid = kids.getArrayItem(i);
101 if (!kid.isDictionary()) { 105 if (!kid.isDictionary()) {
102 kid.warnIfPossible("Pages tree includes non-dictionary object; ignoring"); 106 kid.warnIfPossible("Pages tree includes non-dictionary object; ignoring");
  107 + m->invalid_page_found = true;
103 continue; 108 continue;
104 } 109 }
105 if (kid.hasKey("/Kids")) { 110 if (kid.hasKey("/Kids")) {
@@ -181,7 +186,11 @@ QPDF::flattenPagesTree() @@ -181,7 +186,11 @@ QPDF::flattenPagesTree()
181 pages.replaceKey("/Kids", QPDFObjectHandle::newArray(m->all_pages)); 186 pages.replaceKey("/Kids", QPDFObjectHandle::newArray(m->all_pages));
182 // /Count has not changed 187 // /Count has not changed
183 if (pages.getKey("/Count").getUIntValue() != len) { 188 if (pages.getKey("/Count").getUIntValue() != len) {
184 - throw std::runtime_error("/Count is wrong after flattening pages tree"); 189 + if (m->invalid_page_found && pages.getKey("/Count").getUIntValue() > len) {
  190 + pages.replaceKey("/Count", QPDFObjectHandle::newInteger(toI(len)));
  191 + } else {
  192 + throw std::runtime_error("/Count is wrong after flattening pages tree");
  193 + }
185 } 194 }
186 } 195 }
187 196