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 11 2019-06-22 Jay Berkenbilt <ejb@ql.org>
2 12  
3 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 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 139 std::vector<int>& numbers)
140 140 {
141 141 numbers.push_back(0);
142   - for (std::list<QPDFOutlineObjectHelper>::iterator iter = outlines.begin();
  142 + for (std::vector<QPDFOutlineObjectHelper>::iterator iter = outlines.begin();
143 143 iter != outlines.end(); ++iter)
144 144 {
145 145 ++(numbers.back());
146 146 show_bookmark_details(*iter, numbers);
147   - std::list<QPDFOutlineObjectHelper>::iterator next = iter;
  147 + std::vector<QPDFOutlineObjectHelper>::iterator next = iter;
148 148 ++next;
149 149 bool has_next = (next != outlines.end());
150 150 if ((style == st_lines) && (! has_next))
... ...
fuzz/qpdf_fuzzer.cc
... ... @@ -170,13 +170,13 @@ void
170 170 FuzzHelper::testOutlines()
171 171 {
172 172 PointerHolder<QPDF> q = getQpdf();
173   - std::list<std::list<QPDFOutlineObjectHelper> > queue;
  173 + std::list<std::vector<QPDFOutlineObjectHelper> > queue;
174 174 QPDFOutlineDocumentHelper odh(*q);
175 175 queue.push_back(odh.getTopLevelOutlines());
176 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 180 outlines.begin();
181 181 iter != outlines.end(); ++iter)
182 182 {
... ...
include/qpdf/QPDFOutlineDocumentHelper.hh
... ... @@ -28,8 +28,8 @@
28 28  
29 29 #include <qpdf/QPDF.hh>
30 30 #include <map>
31   -#include <list>
32 31 #include <set>
  32 +#include <vector>
33 33  
34 34 #include <qpdf/DLL.h>
35 35  
... ... @@ -51,7 +51,7 @@ class QPDFOutlineDocumentHelper: public QPDFDocumentHelper
51 51 bool hasOutlines();
52 52  
53 53 QPDF_DLL
54   - std::list<QPDFOutlineObjectHelper> getTopLevelOutlines();
  54 + std::vector<QPDFOutlineObjectHelper> getTopLevelOutlines();
55 55  
56 56 // If the name is a name object, look it up in the /Dests key of
57 57 // the document catalog. If the name is a string, look it up in
... ... @@ -64,7 +64,7 @@ class QPDFOutlineDocumentHelper: public QPDFDocumentHelper
64 64 // Return a list outlines that are known to target the specified
65 65 // page
66 66 QPDF_DLL
67   - std::list<QPDFOutlineObjectHelper> getOutlinesForPage(QPDFObjGen const&);
  67 + std::vector<QPDFOutlineObjectHelper> getOutlinesForPage(QPDFObjGen const&);
68 68  
69 69 class Accessor
70 70 {
... ... @@ -95,11 +95,11 @@ class QPDFOutlineDocumentHelper: public QPDFDocumentHelper
95 95 Members();
96 96 Members(Members const&);
97 97  
98   - std::list<QPDFOutlineObjectHelper> outlines;
  98 + std::vector<QPDFOutlineObjectHelper> outlines;
99 99 std::set<QPDFObjGen> seen;
100 100 QPDFObjectHandle dest_dict;
101 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 105 PointerHolder<Members> m;
... ...
include/qpdf/QPDFOutlineObjectHelper.hh
... ... @@ -24,7 +24,7 @@
24 24  
25 25 #include <qpdf/QPDFObjectHelper.hh>
26 26 #include <qpdf/QPDFObjGen.hh>
27   -#include <list>
  27 +#include <vector>
28 28  
29 29 class QPDFOutlineDocumentHelper;
30 30  
... ... @@ -55,7 +55,7 @@ class QPDFOutlineObjectHelper: public QPDFObjectHelper
55 55  
56 56 // Return children as a list.
57 57 QPDF_DLL
58   - std::list<QPDFOutlineObjectHelper> getKids();
  58 + std::vector<QPDFOutlineObjectHelper> getKids();
59 59  
60 60 // Return the destination, regardless of whether it is named or
61 61 // explicit and whether it is directly provided or in a GoTo
... ... @@ -113,7 +113,7 @@ class QPDFOutlineObjectHelper: public QPDFObjectHelper
113 113  
114 114 QPDFOutlineDocumentHelper& dh;
115 115 PointerHolder<QPDFOutlineObjectHelper> parent;
116   - std::list<QPDFOutlineObjectHelper> kids;
  116 + std::vector<QPDFOutlineObjectHelper> kids;
117 117 };
118 118  
119 119 PointerHolder<Members> m;
... ...
libqpdf/QPDFOutlineDocumentHelper.cc
... ... @@ -42,7 +42,7 @@ QPDFOutlineDocumentHelper::hasOutlines()
42 42 return ! this->m->outlines.empty();
43 43 }
44 44  
45   -std::list<QPDFOutlineObjectHelper>
  45 +std::vector<QPDFOutlineObjectHelper>
46 46 QPDFOutlineDocumentHelper::getTopLevelOutlines()
47 47 {
48 48 return this->m->outlines;
... ... @@ -59,19 +59,19 @@ QPDFOutlineDocumentHelper::initializeByPage()
59 59 QPDFOutlineObjectHelper oh = queue.front();
60 60 queue.pop_front();
61 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 63 queue.insert(queue.end(), kids.begin(), kids.end());
64 64 }
65 65 }
66 66  
67   -std::list<QPDFOutlineObjectHelper>
  67 +std::vector<QPDFOutlineObjectHelper>
68 68 QPDFOutlineDocumentHelper::getOutlinesForPage(QPDFObjGen const& og)
69 69 {
70 70 if (this->m->by_page.empty())
71 71 {
72 72 initializeByPage();
73 73 }
74   - std::list<QPDFOutlineObjectHelper> result;
  74 + std::vector<QPDFOutlineObjectHelper> result;
75 75 if (this->m->by_page.count(og))
76 76 {
77 77 result = this->m->by_page[og];
... ...
libqpdf/QPDFOutlineObjectHelper.cc
... ... @@ -45,7 +45,7 @@ QPDFOutlineObjectHelper::getParent()
45 45 return this->m->parent;
46 46 }
47 47  
48   -std::list<QPDFOutlineObjectHelper>
  48 +std::vector<QPDFOutlineObjectHelper>
49 49 QPDFOutlineObjectHelper::getKids()
50 50 {
51 51 return this->m->kids;
... ...
manual/qpdf-manual.xml
... ... @@ -4316,6 +4316,16 @@ print &quot;\n&quot;;
4316 4316 </listitem>
4317 4317 <listitem>
4318 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 4329 When <command>qpdf --check</command> or <command>qpdf
4320 4330 --check-linearization</command> encounters a file with
4321 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 3493 "label", pldh.getLabelForPage(pageno).getJSON());
3494 3494 JSON j_outlines = j_page.addDictionaryMember(
3495 3495 "outlines", JSON::makeArray());
3496   - std::list<QPDFOutlineObjectHelper> outlines =
  3496 + std::vector<QPDFOutlineObjectHelper> outlines =
3497 3497 odh.getOutlinesForPage(page.getObjGen());
3498   - for (std::list<QPDFOutlineObjectHelper>::iterator oiter =
  3498 + for (std::vector<QPDFOutlineObjectHelper>::iterator oiter =
3499 3499 outlines.begin();
3500 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 3543 }
3544 3544  
3545 3545 static void add_outlines_to_json(
3546   - std::list<QPDFOutlineObjectHelper> outlines, JSON& j,
  3546 + std::vector<QPDFOutlineObjectHelper> outlines, JSON& j,
3547 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 3550 iter != outlines.end(); ++iter)
3551 3551 {
3552 3552 QPDFOutlineObjectHelper& ol = *iter;
... ...
qpdf/test_driver.cc
... ... @@ -1805,9 +1805,9 @@ void runtest(int n, char const* filename1, char const* arg2)
1805 1805 for (std::vector<QPDFPageObjectHelper>::iterator iter = pages.begin();
1806 1806 iter != pages.end(); ++iter, ++pageno)
1807 1807 {
1808   - std::list<QPDFOutlineObjectHelper> outlines =
  1808 + std::vector<QPDFOutlineObjectHelper> outlines =
1809 1809 odh.getOutlinesForPage((*iter).getObjectHandle().getObjGen());
1810   - for (std::list<QPDFOutlineObjectHelper>::iterator oiter =
  1810 + for (std::vector<QPDFOutlineObjectHelper>::iterator oiter =
1811 1811 outlines.begin();
1812 1812 oiter != outlines.end(); ++oiter)
1813 1813 {
... ...