Commit 1bb23d0545dfe2d651cb22b6135d99c1c9ef85d5
1 parent
cedb37ca
Refactor QPDF_Array::insertItem and rename to insert
Showing
8 changed files
with
34 additions
and
34 deletions
libqpdf/QPDFObjectHandle.cc
| @@ -932,9 +932,12 @@ QPDFObjectHandle::setArrayFromVector(std::vector<QPDFObjectHandle> const& items) | @@ -932,9 +932,12 @@ QPDFObjectHandle::setArrayFromVector(std::vector<QPDFObjectHandle> const& items) | ||
| 932 | void | 932 | void |
| 933 | QPDFObjectHandle::insertItem(int at, QPDFObjectHandle const& item) | 933 | QPDFObjectHandle::insertItem(int at, QPDFObjectHandle const& item) |
| 934 | { | 934 | { |
| 935 | - auto array = asArray(); | ||
| 936 | - if (array) { | ||
| 937 | - array->insertItem(at, item); | 935 | + if (auto array = asArray()) { |
| 936 | + if (!array->insert(at, item)) { | ||
| 937 | + objectWarning( | ||
| 938 | + "ignoring attempt to insert out of bounds array item"); | ||
| 939 | + QTC::TC("qpdf", "QPDFObjectHandle insert array bounds"); | ||
| 940 | + } | ||
| 938 | } else { | 941 | } else { |
| 939 | typeWarning("array", "ignoring attempt to insert item"); | 942 | typeWarning("array", "ignoring attempt to insert item"); |
| 940 | QTC::TC("qpdf", "QPDFObjectHandle array ignoring insert item"); | 943 | QTC::TC("qpdf", "QPDFObjectHandle array ignoring insert item"); |
libqpdf/QPDF_Array.cc
| @@ -236,31 +236,24 @@ QPDF_Array::setFromVector(std::vector<std::shared_ptr<QPDFObject>>&& v) | @@ -236,31 +236,24 @@ QPDF_Array::setFromVector(std::vector<std::shared_ptr<QPDFObject>>&& v) | ||
| 236 | } | 236 | } |
| 237 | } | 237 | } |
| 238 | 238 | ||
| 239 | -void | ||
| 240 | -QPDF_Array::insertItem(int at, QPDFObjectHandle const& item) | 239 | +bool |
| 240 | +QPDF_Array::insert(int at, QPDFObjectHandle const& item) | ||
| 241 | { | 241 | { |
| 242 | - if (sparse) { | 242 | + int sz = size(); |
| 243 | + if (at < 0 || at > sz) { | ||
| 243 | // As special case, also allow insert beyond the end | 244 | // As special case, also allow insert beyond the end |
| 244 | - if ((at < 0) || (at > sp_elements.size())) { | ||
| 245 | - throw std::logic_error( | ||
| 246 | - "INTERNAL ERROR: bounds error accessing QPDF_Array element"); | ||
| 247 | - } | ||
| 248 | - sp_elements.insert(at, item); | 245 | + return false; |
| 246 | + } else if (at == sz) { | ||
| 247 | + push_back(item); | ||
| 249 | } else { | 248 | } else { |
| 250 | - // As special case, also allow insert beyond the end | ||
| 251 | - size_t idx = QIntC::to_size(at); | ||
| 252 | - if ((at < 0) || (at > QIntC::to_int(elements.size()))) { | ||
| 253 | - throw std::logic_error( | ||
| 254 | - "INTERNAL ERROR: bounds error accessing QPDF_Array element"); | ||
| 255 | - } | ||
| 256 | - if (idx == elements.size()) { | ||
| 257 | - // Allow inserting to the last position | ||
| 258 | - elements.push_back(item.getObj()); | 249 | + checkOwnership(item); |
| 250 | + if (sparse) { | ||
| 251 | + sp_elements.insert(at, item); | ||
| 259 | } else { | 252 | } else { |
| 260 | - int n = int(idx); | ||
| 261 | - elements.insert(elements.cbegin() + n, item.getObj()); | 253 | + elements.insert(elements.cbegin() + at, item.getObj()); |
| 262 | } | 254 | } |
| 263 | } | 255 | } |
| 256 | + return true; | ||
| 264 | } | 257 | } |
| 265 | 258 | ||
| 266 | void | 259 | void |
libqpdf/SparseOHArray.cc
| @@ -64,23 +64,23 @@ SparseOHArray::erase(int idx) | @@ -64,23 +64,23 @@ SparseOHArray::erase(int idx) | ||
| 64 | void | 64 | void |
| 65 | SparseOHArray::insert(int idx, QPDFObjectHandle oh) | 65 | SparseOHArray::insert(int idx, QPDFObjectHandle oh) |
| 66 | { | 66 | { |
| 67 | - if (idx > this->n_elements) { | ||
| 68 | - throw std::logic_error("bounds error inserting item to SparseOHArray"); | ||
| 69 | - } else if (idx == this->n_elements) { | 67 | + if (idx == n_elements) { |
| 70 | // Allow inserting to the last position | 68 | // Allow inserting to the last position |
| 71 | append(oh); | 69 | append(oh); |
| 72 | } else { | 70 | } else { |
| 73 | - decltype(this->elements) dest; | ||
| 74 | - for (auto const& iter: this->elements) { | ||
| 75 | - if (iter.first < idx) { | ||
| 76 | - dest.insert(iter); | 71 | + auto iter = elements.crbegin(); |
| 72 | + while (iter != elements.crend()) { | ||
| 73 | + auto key = (iter++)->first; | ||
| 74 | + if (key >= idx) { | ||
| 75 | + auto nh = elements.extract(key); | ||
| 76 | + ++nh.key(); | ||
| 77 | + elements.insert(std::move(nh)); | ||
| 77 | } else { | 78 | } else { |
| 78 | - dest[iter.first + 1] = iter.second; | 79 | + break; |
| 79 | } | 80 | } |
| 80 | } | 81 | } |
| 81 | - this->elements = dest; | ||
| 82 | - this->elements[idx] = oh.getObj(); | ||
| 83 | - ++this->n_elements; | 82 | + elements[idx] = oh.getObj(); |
| 83 | + ++n_elements; | ||
| 84 | } | 84 | } |
| 85 | } | 85 | } |
| 86 | 86 |
libqpdf/qpdf/QPDF_Array.hh
| @@ -33,7 +33,7 @@ class QPDF_Array: public QPDFValue | @@ -33,7 +33,7 @@ class QPDF_Array: public QPDFValue | ||
| 33 | void setItem(int, QPDFObjectHandle const&); | 33 | void setItem(int, QPDFObjectHandle const&); |
| 34 | void setFromVector(std::vector<QPDFObjectHandle> const& items); | 34 | void setFromVector(std::vector<QPDFObjectHandle> const& items); |
| 35 | void setFromVector(std::vector<std::shared_ptr<QPDFObject>>&& items); | 35 | void setFromVector(std::vector<std::shared_ptr<QPDFObject>>&& items); |
| 36 | - void insertItem(int at, QPDFObjectHandle const& item); | 36 | + bool insert(int at, QPDFObjectHandle const& item); |
| 37 | void push_back(QPDFObjectHandle const& item); | 37 | void push_back(QPDFObjectHandle const& item); |
| 38 | void eraseItem(int at); | 38 | void eraseItem(int at); |
| 39 | 39 |
qpdf/qpdf.testcov
| @@ -305,6 +305,7 @@ QPDFObjectHandle array treating as empty vector 0 | @@ -305,6 +305,7 @@ QPDFObjectHandle array treating as empty vector 0 | ||
| 305 | QPDFObjectHandle array ignoring set item 0 | 305 | QPDFObjectHandle array ignoring set item 0 |
| 306 | QPDFObjectHandle array ignoring replace items 0 | 306 | QPDFObjectHandle array ignoring replace items 0 |
| 307 | QPDFObjectHandle array ignoring insert item 0 | 307 | QPDFObjectHandle array ignoring insert item 0 |
| 308 | +QPDFObjectHandle insert array bounds 0 | ||
| 308 | QPDFObjectHandle array ignoring append item 0 | 309 | QPDFObjectHandle array ignoring append item 0 |
| 309 | QPDFObjectHandle array ignoring erase item 0 | 310 | QPDFObjectHandle array ignoring erase item 0 |
| 310 | QPDFObjectHandle dictionary false for hasKey 0 | 311 | QPDFObjectHandle dictionary false for hasKey 0 |
qpdf/qtest/qpdf/object-types-os.out
| @@ -5,6 +5,7 @@ WARNING: object-types-os.pdf object stream 1, object 7 0 at offset 429: operatio | @@ -5,6 +5,7 @@ WARNING: object-types-os.pdf object stream 1, object 7 0 at offset 429: operatio | ||
| 5 | WARNING: object-types-os.pdf object stream 1, object 7 0 at offset 429: operation for array attempted on object of type integer: ignoring attempt to append item | 5 | WARNING: object-types-os.pdf object stream 1, object 7 0 at offset 429: operation for array attempted on object of type integer: ignoring attempt to append item |
| 6 | WARNING: object-types-os.pdf object stream 1, object 7 0 at offset 384: ignoring attempt to erase out of bounds array item | 6 | WARNING: object-types-os.pdf object stream 1, object 7 0 at offset 384: ignoring attempt to erase out of bounds array item |
| 7 | WARNING: object-types-os.pdf object stream 1, object 7 0 at offset 384: ignoring attempt to erase out of bounds array item | 7 | WARNING: object-types-os.pdf object stream 1, object 7 0 at offset 384: ignoring attempt to erase out of bounds array item |
| 8 | +WARNING: object-types-os.pdf object stream 1, object 7 0 at offset 384: ignoring attempt to insert out of bounds array item | ||
| 8 | WARNING: object-types-os.pdf object stream 1, object 7 0 at offset 429: operation for array attempted on object of type integer: ignoring attempt to erase item | 9 | WARNING: object-types-os.pdf object stream 1, object 7 0 at offset 429: operation for array attempted on object of type integer: ignoring attempt to erase item |
| 9 | WARNING: object-types-os.pdf object stream 1, object 7 0 at offset 429: operation for array attempted on object of type integer: ignoring attempt to insert item | 10 | WARNING: object-types-os.pdf object stream 1, object 7 0 at offset 429: operation for array attempted on object of type integer: ignoring attempt to insert item |
| 10 | WARNING: object-types-os.pdf object stream 1, object 7 0 at offset 429: operation for array attempted on object of type integer: ignoring attempt to replace items | 11 | WARNING: object-types-os.pdf object stream 1, object 7 0 at offset 429: operation for array attempted on object of type integer: ignoring attempt to replace items |
qpdf/qtest/qpdf/object-types.out
| @@ -5,6 +5,7 @@ WARNING: object-types.pdf, object 8 0 at offset 669: operation for array attempt | @@ -5,6 +5,7 @@ WARNING: object-types.pdf, object 8 0 at offset 669: operation for array attempt | ||
| 5 | WARNING: object-types.pdf, object 8 0 at offset 669: operation for array attempted on object of type integer: ignoring attempt to append item | 5 | WARNING: object-types.pdf, object 8 0 at offset 669: operation for array attempted on object of type integer: ignoring attempt to append item |
| 6 | WARNING: object-types.pdf, object 8 0 at offset 717: ignoring attempt to erase out of bounds array item | 6 | WARNING: object-types.pdf, object 8 0 at offset 717: ignoring attempt to erase out of bounds array item |
| 7 | WARNING: object-types.pdf, object 8 0 at offset 717: ignoring attempt to erase out of bounds array item | 7 | WARNING: object-types.pdf, object 8 0 at offset 717: ignoring attempt to erase out of bounds array item |
| 8 | +WARNING: object-types.pdf, object 8 0 at offset 717: ignoring attempt to insert out of bounds array item | ||
| 8 | WARNING: object-types.pdf, object 8 0 at offset 669: operation for array attempted on object of type integer: ignoring attempt to erase item | 9 | WARNING: object-types.pdf, object 8 0 at offset 669: operation for array attempted on object of type integer: ignoring attempt to erase item |
| 9 | WARNING: object-types.pdf, object 8 0 at offset 669: operation for array attempted on object of type integer: ignoring attempt to insert item | 10 | WARNING: object-types.pdf, object 8 0 at offset 669: operation for array attempted on object of type integer: ignoring attempt to insert item |
| 10 | WARNING: object-types.pdf, object 8 0 at offset 669: operation for array attempted on object of type integer: ignoring attempt to replace items | 11 | WARNING: object-types.pdf, object 8 0 at offset 669: operation for array attempted on object of type integer: ignoring attempt to replace items |
qpdf/test_driver.cc
| @@ -1506,6 +1506,7 @@ test_42(QPDF& pdf, char const* arg2) | @@ -1506,6 +1506,7 @@ test_42(QPDF& pdf, char const* arg2) | ||
| 1506 | integer.appendItem(null); | 1506 | integer.appendItem(null); |
| 1507 | array.eraseItem(-1); | 1507 | array.eraseItem(-1); |
| 1508 | array.eraseItem(16059); | 1508 | array.eraseItem(16059); |
| 1509 | + array.insertItem(42, "/Dontpanic"_qpdf); | ||
| 1509 | integer.eraseItem(0); | 1510 | integer.eraseItem(0); |
| 1510 | integer.insertItem(0, null); | 1511 | integer.insertItem(0, null); |
| 1511 | integer.setArrayFromVector(std::vector<QPDFObjectHandle>()); | 1512 | integer.setArrayFromVector(std::vector<QPDFObjectHandle>()); |