Commit 9da50ca3601ee58c2ccceaa5d430b56a1ab27306

Authored by m-holger
Committed by Jay Berkenbilt
1 parent e91e642c

Change olist variable in QPDFParser::parse to vector<shared_ptr<QPDFObject>>

include/qpdf/QPDFObjectHandle.hh
... ... @@ -1608,12 +1608,12 @@ class QPDFObjectHandle
1608 1608 QPDF_DLL
1609 1609 bool isImage(bool exclude_imagemask = true);
1610 1610  
1611   - private:
1612 1611 QPDFObjectHandle(std::shared_ptr<QPDFObject> const& obj) :
1613 1612 obj(obj)
1614 1613 {
1615 1614 }
1616 1615  
  1616 + private:
1617 1617 QPDF_Array* asArray();
1618 1618 QPDF_Bool* asBool();
1619 1619 QPDF_Dictionary* asDictionary();
... ...
libqpdf/QPDFParser.cc
... ... @@ -33,7 +33,7 @@ namespace
33 33 {
34 34 }
35 35  
36   - std::vector<QPDFObjectHandle> olist;
  36 + std::vector<std::shared_ptr<QPDFObject>> olist;
37 37 qpdf_offset_t offset;
38 38 std::string contents_string;
39 39 qpdf_offset_t contents_offset;
... ... @@ -67,7 +67,7 @@ QPDFParser::parse(bool&amp; empty, bool content_stream)
67 67 int good_count = 0;
68 68 bool b_contents = false;
69 69 bool is_null = false;
70   - auto null_oh = QPDFObjectHandle::newNull();
  70 + auto null_oh = QPDF_Null::create();
71 71  
72 72 while (!done) {
73 73 bool bad = false;
... ... @@ -191,11 +191,13 @@ QPDFParser::parse(bool&amp; empty, bool content_stream)
191 191 if (content_stream) {
192 192 object = QPDF_Operator::create(value);
193 193 } else if (
194   - (value == "R") && (state != st_top) && (size >= 2) &&
195   - (!olist.back().isIndirect()) &&
196   - (olist.back().isInteger()) &&
197   - (!olist.at(size - 2).isIndirect()) &&
198   - (olist.at(size - 2).isInteger())) {
  194 + value == "R" && state != st_top && size >= 2 &&
  195 + olist.back() &&
  196 + olist.back()->getTypeCode() == ::ot_integer &&
  197 + !olist.back()->getObjGen().isIndirect() &&
  198 + olist.at(size - 2) &&
  199 + olist.at(size - 2)->getTypeCode() == ::ot_integer &&
  200 + !olist.at(size - 2)->getObjGen().isIndirect()) {
199 201 if (context == nullptr) {
200 202 QTC::TC("qpdf", "QPDFParser indirect without context");
201 203 throw std::logic_error(
... ... @@ -203,8 +205,8 @@ QPDFParser::parse(bool&amp; empty, bool content_stream)
203 205 " on an object with indirect references");
204 206 }
205 207 auto ref_og = QPDFObjGen(
206   - olist.at(size - 2).getIntValueAsInt(),
207   - olist.back().getIntValueAsInt());
  208 + QPDFObjectHandle(olist.at(size - 2)).getIntValueAsInt(),
  209 + QPDFObjectHandle(olist.back()).getIntValueAsInt());
208 210 if (ref_og.isIndirect()) {
209 211 // This action has the desirable side effect
210 212 // of causing dangling references (references
... ... @@ -306,7 +308,7 @@ QPDFParser::parse(bool&amp; empty, bool content_stream)
306 308 setDescription(object, input->getLastOffset());
307 309 }
308 310 set_offset = true;
309   - olist.push_back(is_null ? null_oh : QPDFObjectHandle(object));
  311 + olist.push_back(is_null ? null_oh : object);
310 312 break;
311 313  
312 314 case st_top:
... ... @@ -325,7 +327,7 @@ QPDFParser::parse(bool&amp; empty, bool content_stream)
325 327 parser_state_e old_state = state_stack.back();
326 328 state_stack.pop_back();
327 329 if (old_state == st_array) {
328   - object = QPDF_Array::create(olist);
  330 + object = QPDF_Array::create(std::move(olist));
329 331 setDescription(object, offset - 1);
330 332 // The `offset` points to the next of "[". Set the rewind
331 333 // offset to point to the beginning of "[". This has been
... ... @@ -412,8 +414,7 @@ QPDFParser::parse(bool&amp; empty, bool content_stream)
412 414 if (state_stack.back() == st_top) {
413 415 done = true;
414 416 } else {
415   - stack.back().olist.push_back(
416   - is_null ? null_oh : QPDFObjectHandle(object));
  417 + stack.back().olist.push_back(is_null ? null_oh : object);
417 418 }
418 419 }
419 420 }
... ...
libqpdf/QPDF_Array.cc
1 1 #include <qpdf/QPDF_Array.hh>
2 2  
3 3 #include <qpdf/QIntC.hh>
  4 +#include <qpdf/QPDFObject_private.hh>
4 5 #include <qpdf/QUtil.hh>
5 6 #include <stdexcept>
6 7  
... ... @@ -10,6 +11,12 @@ QPDF_Array::QPDF_Array(std::vector&lt;QPDFObjectHandle&gt; const&amp; v) :
10 11 setFromVector(v);
11 12 }
12 13  
  14 +QPDF_Array::QPDF_Array(std::vector<std::shared_ptr<QPDFObject>>&& v) :
  15 + QPDFValue(::ot_array, "array")
  16 +{
  17 + setFromVector(std::move(v));
  18 +}
  19 +
13 20 QPDF_Array::QPDF_Array(SparseOHArray const& items) :
14 21 QPDFValue(::ot_array, "array"),
15 22 elements(items)
... ... @@ -23,6 +30,12 @@ QPDF_Array::create(std::vector&lt;QPDFObjectHandle&gt; const&amp; items)
23 30 }
24 31  
25 32 std::shared_ptr<QPDFObject>
  33 +QPDF_Array::create(std::vector<std::shared_ptr<QPDFObject>>&& items)
  34 +{
  35 + return do_create(new QPDF_Array(std::move(items)));
  36 +}
  37 +
  38 +std::shared_ptr<QPDFObject>
26 39 QPDF_Array::create(SparseOHArray const& items)
27 40 {
28 41 return do_create(new QPDF_Array(items));
... ... @@ -107,6 +120,15 @@ QPDF_Array::setFromVector(std::vector&lt;QPDFObjectHandle&gt; const&amp; v)
107 120 }
108 121  
109 122 void
  123 +QPDF_Array::setFromVector(std::vector<std::shared_ptr<QPDFObject>>&& v)
  124 +{
  125 + this->elements = SparseOHArray();
  126 + for (auto&& iter: v) {
  127 + this->elements.append(iter);
  128 + }
  129 +}
  130 +
  131 +void
110 132 QPDF_Array::insertItem(int at, QPDFObjectHandle const& item)
111 133 {
112 134 // As special case, also allow insert beyond the end
... ...
libqpdf/SparseOHArray.cc
1 1 #include <qpdf/SparseOHArray.hh>
2 2  
  3 +#include <qpdf/QPDFObjectHandle.hh>
  4 +#include <qpdf/QPDFObject_private.hh>
  5 +
3 6 #include <stdexcept>
4 7  
5 8 SparseOHArray::SparseOHArray() :
... ... @@ -22,6 +25,15 @@ SparseOHArray::append(QPDFObjectHandle oh)
22 25 ++this->n_elements;
23 26 }
24 27  
  28 +void
  29 +SparseOHArray::append(std::shared_ptr<QPDFObject>&& obj)
  30 +{
  31 + if (obj->getTypeCode() != ::ot_null || !obj->getObjGen().isIndirect()) {
  32 + this->elements[this->n_elements] = std::move(obj);
  33 + }
  34 + ++this->n_elements;
  35 +}
  36 +
25 37 QPDFObjectHandle
26 38 SparseOHArray::at(size_t idx) const
27 39 {
... ...
libqpdf/qpdf/QPDF_Array.hh
... ... @@ -13,6 +13,8 @@ class QPDF_Array: public QPDFValue
13 13 virtual ~QPDF_Array() = default;
14 14 static std::shared_ptr<QPDFObject>
15 15 create(std::vector<QPDFObjectHandle> const& items);
  16 + static std::shared_ptr<QPDFObject>
  17 + create(std::vector<std::shared_ptr<QPDFObject>>&& items);
16 18 static std::shared_ptr<QPDFObject> create(SparseOHArray const& items);
17 19 virtual std::shared_ptr<QPDFObject> copy(bool shallow = false);
18 20 virtual std::string unparse();
... ... @@ -25,6 +27,7 @@ class QPDF_Array: public QPDFValue
25 27  
26 28 void setItem(int, QPDFObjectHandle const&);
27 29 void setFromVector(std::vector<QPDFObjectHandle> const& items);
  30 + void setFromVector(std::vector<std::shared_ptr<QPDFObject>>&& items);
28 31 void insertItem(int at, QPDFObjectHandle const& item);
29 32 void appendItem(QPDFObjectHandle const& item);
30 33 void eraseItem(int at);
... ... @@ -36,6 +39,7 @@ class QPDF_Array: public QPDFValue
36 39  
37 40 private:
38 41 QPDF_Array(std::vector<QPDFObjectHandle> const& items);
  42 + QPDF_Array(std::vector<std::shared_ptr<QPDFObject>>&& items);
39 43 QPDF_Array(SparseOHArray const& items);
40 44 SparseOHArray elements;
41 45 };
... ...
libqpdf/qpdf/SparseOHArray.hh
... ... @@ -10,6 +10,7 @@ class SparseOHArray
10 10 SparseOHArray();
11 11 size_t size() const;
12 12 void append(QPDFObjectHandle oh);
  13 + void append(std::shared_ptr<QPDFObject>&& obj);
13 14 QPDFObjectHandle at(size_t idx) const;
14 15 void remove_last();
15 16 void setAt(size_t idx, QPDFObjectHandle oh);
... ...