Commit 8f06da75343a5e970ff7a6f275c319172e6292d0

Authored by Thorsten Schöning
Committed by Jay Berkenbilt
1 parent 4db1de97

Change list to vector for outline helpers (fixes #297)

This change works around STL problems with Embarcadero C++ Builder
version 10.2, but std::vector is more common than std::list in qpdf,
and this is a relatively new API, so an API change is tolerable.

Thanks to Thorsten Schöning <6223655+ams-tschoening@users.noreply.github.com>
for the fix.
ChangeLog
  1 +2019-07-03 Jay Berkenbilt <ejb@ql.org>
  2 +
  3 + * Non-compatible API change: change
  4 + QPDFOutlineDocumentHelper::getTopLevelOutlines and
  5 + QPDFOutlineObjectHelper::getKids to return a std::vector instead
  6 + of a std::list of QPDFOutlineObjectHelper objects. This is to work
  7 + around bugs with some compilers' STL implementations that are
  8 + choking with list here. There's no deep reason for these to be
  9 + lists instead of vectors. Fixes #297.
  10 +
1 2019-06-22 Jay Berkenbilt <ejb@ql.org> 11 2019-06-22 Jay Berkenbilt <ejb@ql.org>
2 12
3 * Handle encrypted files with missing or invalid /Length entries 13 * Handle encrypted files with missing or invalid /Length entries
examples/pdf-bookmarks.cc
@@ -135,16 +135,16 @@ void show_bookmark_details(QPDFOutlineObjectHelper outline, @@ -135,16 +135,16 @@ void show_bookmark_details(QPDFOutlineObjectHelper outline,
135 std::cout << outline.getTitle() << std::endl; 135 std::cout << outline.getTitle() << std::endl;
136 } 136 }
137 137
138 -void extract_bookmarks(std::list<QPDFOutlineObjectHelper> outlines, 138 +void extract_bookmarks(std::vector<QPDFOutlineObjectHelper> outlines,
139 std::vector<int>& numbers) 139 std::vector<int>& numbers)
140 { 140 {
141 numbers.push_back(0); 141 numbers.push_back(0);
142 - for (std::list<QPDFOutlineObjectHelper>::iterator iter = outlines.begin(); 142 + for (std::vector<QPDFOutlineObjectHelper>::iterator iter = outlines.begin();
143 iter != outlines.end(); ++iter) 143 iter != outlines.end(); ++iter)
144 { 144 {
145 ++(numbers.back()); 145 ++(numbers.back());
146 show_bookmark_details(*iter, numbers); 146 show_bookmark_details(*iter, numbers);
147 - std::list<QPDFOutlineObjectHelper>::iterator next = iter; 147 + std::vector<QPDFOutlineObjectHelper>::iterator next = iter;
148 ++next; 148 ++next;
149 bool has_next = (next != outlines.end()); 149 bool has_next = (next != outlines.end());
150 if ((style == st_lines) && (! has_next)) 150 if ((style == st_lines) && (! has_next))
fuzz/qpdf_fuzzer.cc
@@ -170,13 +170,13 @@ void @@ -170,13 +170,13 @@ void
170 FuzzHelper::testOutlines() 170 FuzzHelper::testOutlines()
171 { 171 {
172 PointerHolder<QPDF> q = getQpdf(); 172 PointerHolder<QPDF> q = getQpdf();
173 - std::list<std::list<QPDFOutlineObjectHelper> > queue; 173 + std::list<std::vector<QPDFOutlineObjectHelper> > queue;
174 QPDFOutlineDocumentHelper odh(*q); 174 QPDFOutlineDocumentHelper odh(*q);
175 queue.push_back(odh.getTopLevelOutlines()); 175 queue.push_back(odh.getTopLevelOutlines());
176 while (! queue.empty()) 176 while (! queue.empty())
177 { 177 {
178 - std::list<QPDFOutlineObjectHelper>& outlines = *(queue.begin());  
179 - for (std::list<QPDFOutlineObjectHelper>::iterator iter = 178 + std::vector<QPDFOutlineObjectHelper>& outlines = *(queue.begin());
  179 + for (std::vector<QPDFOutlineObjectHelper>::iterator iter =
180 outlines.begin(); 180 outlines.begin();
181 iter != outlines.end(); ++iter) 181 iter != outlines.end(); ++iter)
182 { 182 {
include/qpdf/QPDFOutlineDocumentHelper.hh
@@ -28,8 +28,8 @@ @@ -28,8 +28,8 @@
28 28
29 #include <qpdf/QPDF.hh> 29 #include <qpdf/QPDF.hh>
30 #include <map> 30 #include <map>
31 -#include <list>  
32 #include <set> 31 #include <set>
  32 +#include <vector>
33 33
34 #include <qpdf/DLL.h> 34 #include <qpdf/DLL.h>
35 35
@@ -51,7 +51,7 @@ class QPDFOutlineDocumentHelper: public QPDFDocumentHelper @@ -51,7 +51,7 @@ class QPDFOutlineDocumentHelper: public QPDFDocumentHelper
51 bool hasOutlines(); 51 bool hasOutlines();
52 52
53 QPDF_DLL 53 QPDF_DLL
54 - std::list<QPDFOutlineObjectHelper> getTopLevelOutlines(); 54 + std::vector<QPDFOutlineObjectHelper> getTopLevelOutlines();
55 55
56 // If the name is a name object, look it up in the /Dests key of 56 // If the name is a name object, look it up in the /Dests key of
57 // the document catalog. If the name is a string, look it up in 57 // the document catalog. If the name is a string, look it up in
@@ -64,7 +64,7 @@ class QPDFOutlineDocumentHelper: public QPDFDocumentHelper @@ -64,7 +64,7 @@ class QPDFOutlineDocumentHelper: public QPDFDocumentHelper
64 // Return a list outlines that are known to target the specified 64 // Return a list outlines that are known to target the specified
65 // page 65 // page
66 QPDF_DLL 66 QPDF_DLL
67 - std::list<QPDFOutlineObjectHelper> getOutlinesForPage(QPDFObjGen const&); 67 + std::vector<QPDFOutlineObjectHelper> getOutlinesForPage(QPDFObjGen const&);
68 68
69 class Accessor 69 class Accessor
70 { 70 {
@@ -95,11 +95,11 @@ class QPDFOutlineDocumentHelper: public QPDFDocumentHelper @@ -95,11 +95,11 @@ class QPDFOutlineDocumentHelper: public QPDFDocumentHelper
95 Members(); 95 Members();
96 Members(Members const&); 96 Members(Members const&);
97 97
98 - std::list<QPDFOutlineObjectHelper> outlines; 98 + std::vector<QPDFOutlineObjectHelper> outlines;
99 std::set<QPDFObjGen> seen; 99 std::set<QPDFObjGen> seen;
100 QPDFObjectHandle dest_dict; 100 QPDFObjectHandle dest_dict;
101 PointerHolder<QPDFNameTreeObjectHelper> names_dest; 101 PointerHolder<QPDFNameTreeObjectHelper> names_dest;
102 - std::map<QPDFObjGen, std::list<QPDFOutlineObjectHelper> > by_page; 102 + std::map<QPDFObjGen, std::vector<QPDFOutlineObjectHelper> > by_page;
103 }; 103 };
104 104
105 PointerHolder<Members> m; 105 PointerHolder<Members> m;
include/qpdf/QPDFOutlineObjectHelper.hh
@@ -24,7 +24,7 @@ @@ -24,7 +24,7 @@
24 24
25 #include <qpdf/QPDFObjectHelper.hh> 25 #include <qpdf/QPDFObjectHelper.hh>
26 #include <qpdf/QPDFObjGen.hh> 26 #include <qpdf/QPDFObjGen.hh>
27 -#include <list> 27 +#include <vector>
28 28
29 class QPDFOutlineDocumentHelper; 29 class QPDFOutlineDocumentHelper;
30 30
@@ -55,7 +55,7 @@ class QPDFOutlineObjectHelper: public QPDFObjectHelper @@ -55,7 +55,7 @@ class QPDFOutlineObjectHelper: public QPDFObjectHelper
55 55
56 // Return children as a list. 56 // Return children as a list.
57 QPDF_DLL 57 QPDF_DLL
58 - std::list<QPDFOutlineObjectHelper> getKids(); 58 + std::vector<QPDFOutlineObjectHelper> getKids();
59 59
60 // Return the destination, regardless of whether it is named or 60 // Return the destination, regardless of whether it is named or
61 // explicit and whether it is directly provided or in a GoTo 61 // explicit and whether it is directly provided or in a GoTo
@@ -113,7 +113,7 @@ class QPDFOutlineObjectHelper: public QPDFObjectHelper @@ -113,7 +113,7 @@ class QPDFOutlineObjectHelper: public QPDFObjectHelper
113 113
114 QPDFOutlineDocumentHelper& dh; 114 QPDFOutlineDocumentHelper& dh;
115 PointerHolder<QPDFOutlineObjectHelper> parent; 115 PointerHolder<QPDFOutlineObjectHelper> parent;
116 - std::list<QPDFOutlineObjectHelper> kids; 116 + std::vector<QPDFOutlineObjectHelper> kids;
117 }; 117 };
118 118
119 PointerHolder<Members> m; 119 PointerHolder<Members> m;
libqpdf/QPDFOutlineDocumentHelper.cc
@@ -42,7 +42,7 @@ QPDFOutlineDocumentHelper::hasOutlines() @@ -42,7 +42,7 @@ QPDFOutlineDocumentHelper::hasOutlines()
42 return ! this->m->outlines.empty(); 42 return ! this->m->outlines.empty();
43 } 43 }
44 44
45 -std::list<QPDFOutlineObjectHelper> 45 +std::vector<QPDFOutlineObjectHelper>
46 QPDFOutlineDocumentHelper::getTopLevelOutlines() 46 QPDFOutlineDocumentHelper::getTopLevelOutlines()
47 { 47 {
48 return this->m->outlines; 48 return this->m->outlines;
@@ -59,19 +59,19 @@ QPDFOutlineDocumentHelper::initializeByPage() @@ -59,19 +59,19 @@ QPDFOutlineDocumentHelper::initializeByPage()
59 QPDFOutlineObjectHelper oh = queue.front(); 59 QPDFOutlineObjectHelper oh = queue.front();
60 queue.pop_front(); 60 queue.pop_front();
61 this->m->by_page[oh.getDestPage().getObjGen()].push_back(oh); 61 this->m->by_page[oh.getDestPage().getObjGen()].push_back(oh);
62 - std::list<QPDFOutlineObjectHelper> kids = oh.getKids(); 62 + std::vector<QPDFOutlineObjectHelper> kids = oh.getKids();
63 queue.insert(queue.end(), kids.begin(), kids.end()); 63 queue.insert(queue.end(), kids.begin(), kids.end());
64 } 64 }
65 } 65 }
66 66
67 -std::list<QPDFOutlineObjectHelper> 67 +std::vector<QPDFOutlineObjectHelper>
68 QPDFOutlineDocumentHelper::getOutlinesForPage(QPDFObjGen const& og) 68 QPDFOutlineDocumentHelper::getOutlinesForPage(QPDFObjGen const& og)
69 { 69 {
70 if (this->m->by_page.empty()) 70 if (this->m->by_page.empty())
71 { 71 {
72 initializeByPage(); 72 initializeByPage();
73 } 73 }
74 - std::list<QPDFOutlineObjectHelper> result; 74 + std::vector<QPDFOutlineObjectHelper> result;
75 if (this->m->by_page.count(og)) 75 if (this->m->by_page.count(og))
76 { 76 {
77 result = this->m->by_page[og]; 77 result = this->m->by_page[og];
libqpdf/QPDFOutlineObjectHelper.cc
@@ -45,7 +45,7 @@ QPDFOutlineObjectHelper::getParent() @@ -45,7 +45,7 @@ QPDFOutlineObjectHelper::getParent()
45 return this->m->parent; 45 return this->m->parent;
46 } 46 }
47 47
48 -std::list<QPDFOutlineObjectHelper> 48 +std::vector<QPDFOutlineObjectHelper>
49 QPDFOutlineObjectHelper::getKids() 49 QPDFOutlineObjectHelper::getKids()
50 { 50 {
51 return this->m->kids; 51 return this->m->kids;
manual/qpdf-manual.xml
@@ -4316,6 +4316,16 @@ print &quot;\n&quot;; @@ -4316,6 +4316,16 @@ print &quot;\n&quot;;
4316 </listitem> 4316 </listitem>
4317 <listitem> 4317 <listitem>
4318 <para> 4318 <para>
  4319 + Change
  4320 + <function>QPDFOutlineDocumentHelper::getTopLevelOutlines</function>
  4321 + and <function>QPDFOutlineObjectHelper::getKids</function> to
  4322 + return a <type>std::vector</type> instead of a
  4323 + <type>std::list</type> of
  4324 + <classname>QPDFOutlineObjectHelper</classname> objects.
  4325 + </para>
  4326 + </listitem>
  4327 + <listitem>
  4328 + <para>
4319 When <command>qpdf --check</command> or <command>qpdf 4329 When <command>qpdf --check</command> or <command>qpdf
4320 --check-linearization</command> encounters a file with 4330 --check-linearization</command> encounters a file with
4321 linearization warnings but not errors, it now properly exits 4331 linearization warnings but not errors, it now properly exits
qpdf/qpdf.cc
@@ -3493,9 +3493,9 @@ static void do_json_pages(QPDF&amp; pdf, Options&amp; o, JSON&amp; j) @@ -3493,9 +3493,9 @@ static void do_json_pages(QPDF&amp; pdf, Options&amp; o, JSON&amp; j)
3493 "label", pldh.getLabelForPage(pageno).getJSON()); 3493 "label", pldh.getLabelForPage(pageno).getJSON());
3494 JSON j_outlines = j_page.addDictionaryMember( 3494 JSON j_outlines = j_page.addDictionaryMember(
3495 "outlines", JSON::makeArray()); 3495 "outlines", JSON::makeArray());
3496 - std::list<QPDFOutlineObjectHelper> outlines = 3496 + std::vector<QPDFOutlineObjectHelper> outlines =
3497 odh.getOutlinesForPage(page.getObjGen()); 3497 odh.getOutlinesForPage(page.getObjGen());
3498 - for (std::list<QPDFOutlineObjectHelper>::iterator oiter = 3498 + for (std::vector<QPDFOutlineObjectHelper>::iterator oiter =
3499 outlines.begin(); 3499 outlines.begin();
3500 oiter != outlines.end(); ++oiter) 3500 oiter != outlines.end(); ++oiter)
3501 { 3501 {
@@ -3543,10 +3543,10 @@ static void do_json_page_labels(QPDF&amp; pdf, Options&amp; o, JSON&amp; j) @@ -3543,10 +3543,10 @@ static void do_json_page_labels(QPDF&amp; pdf, Options&amp; o, JSON&amp; j)
3543 } 3543 }
3544 3544
3545 static void add_outlines_to_json( 3545 static void add_outlines_to_json(
3546 - std::list<QPDFOutlineObjectHelper> outlines, JSON& j, 3546 + std::vector<QPDFOutlineObjectHelper> outlines, JSON& j,
3547 std::map<QPDFObjGen, int>& page_numbers) 3547 std::map<QPDFObjGen, int>& page_numbers)
3548 { 3548 {
3549 - for (std::list<QPDFOutlineObjectHelper>::iterator iter = outlines.begin(); 3549 + for (std::vector<QPDFOutlineObjectHelper>::iterator iter = outlines.begin();
3550 iter != outlines.end(); ++iter) 3550 iter != outlines.end(); ++iter)
3551 { 3551 {
3552 QPDFOutlineObjectHelper& ol = *iter; 3552 QPDFOutlineObjectHelper& ol = *iter;
qpdf/test_driver.cc
@@ -1805,9 +1805,9 @@ void runtest(int n, char const* filename1, char const* arg2) @@ -1805,9 +1805,9 @@ void runtest(int n, char const* filename1, char const* arg2)
1805 for (std::vector<QPDFPageObjectHelper>::iterator iter = pages.begin(); 1805 for (std::vector<QPDFPageObjectHelper>::iterator iter = pages.begin();
1806 iter != pages.end(); ++iter, ++pageno) 1806 iter != pages.end(); ++iter, ++pageno)
1807 { 1807 {
1808 - std::list<QPDFOutlineObjectHelper> outlines = 1808 + std::vector<QPDFOutlineObjectHelper> outlines =
1809 odh.getOutlinesForPage((*iter).getObjectHandle().getObjGen()); 1809 odh.getOutlinesForPage((*iter).getObjectHandle().getObjGen());
1810 - for (std::list<QPDFOutlineObjectHelper>::iterator oiter = 1810 + for (std::vector<QPDFOutlineObjectHelper>::iterator oiter =
1811 outlines.begin(); 1811 outlines.begin();
1812 oiter != outlines.end(); ++oiter) 1812 oiter != outlines.end(); ++oiter)
1813 { 1813 {