Commit 1bb23d0545dfe2d651cb22b6135d99c1c9ef85d5

Authored by m-holger
1 parent cedb37ca

Refactor QPDF_Array::insertItem and rename to insert

libqpdf/QPDFObjectHandle.cc
... ... @@ -932,9 +932,12 @@ QPDFObjectHandle::setArrayFromVector(std::vector<QPDFObjectHandle> const& items)
932 932 void
933 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 941 } else {
939 942 typeWarning("array", "ignoring attempt to insert item");
940 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 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 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 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 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 259 void
... ...
libqpdf/SparseOHArray.cc
... ... @@ -64,23 +64,23 @@ SparseOHArray::erase(int idx)
64 64 void
65 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 68 // Allow inserting to the last position
71 69 append(oh);
72 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 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 33 void setItem(int, QPDFObjectHandle const&);
34 34 void setFromVector(std::vector<QPDFObjectHandle> const& items);
35 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 37 void push_back(QPDFObjectHandle const& item);
38 38 void eraseItem(int at);
39 39  
... ...
qpdf/qpdf.testcov
... ... @@ -305,6 +305,7 @@ QPDFObjectHandle array treating as empty vector 0
305 305 QPDFObjectHandle array ignoring set item 0
306 306 QPDFObjectHandle array ignoring replace items 0
307 307 QPDFObjectHandle array ignoring insert item 0
  308 +QPDFObjectHandle insert array bounds 0
308 309 QPDFObjectHandle array ignoring append item 0
309 310 QPDFObjectHandle array ignoring erase item 0
310 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 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 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 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 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 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 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 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 6 WARNING: object-types.pdf, object 8 0 at offset 717: ignoring attempt to erase out of bounds array item
7 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 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 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 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&amp; pdf, char const* arg2)
1506 1506 integer.appendItem(null);
1507 1507 array.eraseItem(-1);
1508 1508 array.eraseItem(16059);
  1509 + array.insertItem(42, "/Dontpanic"_qpdf);
1509 1510 integer.eraseItem(0);
1510 1511 integer.insertItem(0, null);
1511 1512 integer.setArrayFromVector(std::vector<QPDFObjectHandle>());
... ...