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,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&amp; pdf, char const* arg2) @@ -1506,6 +1506,7 @@ test_42(QPDF&amp; 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>());