Commit 9da50ca3601ee58c2ccceaa5d430b56a1ab27306
Committed by
Jay Berkenbilt
1 parent
e91e642c
Change olist variable in QPDFParser::parse to vector<shared_ptr<QPDFObject>>
Showing
6 changed files
with
54 additions
and
14 deletions
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& 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& 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& 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& 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& 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& 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<QPDFObjectHandle> const& 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<QPDFObjectHandle> const& 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<QPDFObjectHandle> const& 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); | ... | ... |