Commit 4d37389befc705b671d8fa7a1da2b7117b50f454

Authored by m-holger
1 parent 1bb23d05

Refactor QPDF_Array::eraseItem and rename to erase

libqpdf/QPDFObjectHandle.cc
@@ -972,17 +972,14 @@ QPDFObjectHandle::appendItemAndGetNew(QPDFObjectHandle const& item) @@ -972,17 +972,14 @@ QPDFObjectHandle::appendItemAndGetNew(QPDFObjectHandle const& item)
972 void 972 void
973 QPDFObjectHandle::eraseItem(int at) 973 QPDFObjectHandle::eraseItem(int at)
974 { 974 {
975 - auto array = asArray();  
976 - if (array && at < array->size() && at >= 0) {  
977 - array->eraseItem(at);  
978 - } else {  
979 - if (array) { 975 + if (auto array = asArray()) {
  976 + if (!array->erase(at)) {
980 objectWarning("ignoring attempt to erase out of bounds array item"); 977 objectWarning("ignoring attempt to erase out of bounds array item");
981 QTC::TC("qpdf", "QPDFObjectHandle erase array bounds"); 978 QTC::TC("qpdf", "QPDFObjectHandle erase array bounds");
982 - } else {  
983 - typeWarning("array", "ignoring attempt to erase item");  
984 - QTC::TC("qpdf", "QPDFObjectHandle array ignoring erase item");  
985 } 979 }
  980 + } else {
  981 + typeWarning("array", "ignoring attempt to erase item");
  982 + QTC::TC("qpdf", "QPDFObjectHandle array ignoring erase item");
986 } 983 }
987 } 984 }
988 985
libqpdf/QPDF_Array.cc
@@ -267,17 +267,16 @@ QPDF_Array::push_back(QPDFObjectHandle const&amp; item) @@ -267,17 +267,16 @@ QPDF_Array::push_back(QPDFObjectHandle const&amp; item)
267 } 267 }
268 } 268 }
269 269
270 -void  
271 -QPDF_Array::eraseItem(int at) 270 +bool
  271 +QPDF_Array::erase(int at)
272 { 272 {
  273 + if (at < 0 || at >= size()) {
  274 + return false;
  275 + }
273 if (sparse) { 276 if (sparse) {
274 sp_elements.erase(at); 277 sp_elements.erase(at);
275 } else { 278 } else {
276 - size_t idx = QIntC::to_size(at);  
277 - if (idx >= elements.size()) {  
278 - throw std::logic_error("bounds error erasing item from OHArray");  
279 - }  
280 - int n = int(idx);  
281 - elements.erase(elements.cbegin() + n); 279 + elements.erase(elements.cbegin() + at);
282 } 280 }
  281 + return true;
283 } 282 }
libqpdf/SparseOHArray.cc
@@ -44,21 +44,22 @@ SparseOHArray::setAt(int idx, QPDFObjectHandle oh) @@ -44,21 +44,22 @@ SparseOHArray::setAt(int idx, QPDFObjectHandle oh)
44 } 44 }
45 45
46 void 46 void
47 -SparseOHArray::erase(int idx) 47 +SparseOHArray::erase(int at)
48 { 48 {
49 - if (idx >= this->n_elements) {  
50 - throw std::logic_error("bounds error erasing item from SparseOHArray");  
51 - }  
52 - decltype(this->elements) dest;  
53 - for (auto const& iter: this->elements) {  
54 - if (iter.first < idx) {  
55 - dest.insert(iter);  
56 - } else if (iter.first > idx) {  
57 - dest[iter.first - 1] = iter.second; 49 + auto end = elements.end();
  50 + if (auto iter = elements.lower_bound(at); iter != end) {
  51 + if (iter->first == at) {
  52 + iter++;
  53 + elements.erase(at);
  54 + }
  55 +
  56 + while (iter != end) {
  57 + auto nh = elements.extract(iter++);
  58 + --nh.key();
  59 + elements.insert(std::move(nh));
58 } 60 }
59 } 61 }
60 - this->elements = dest;  
61 - --this->n_elements; 62 + --n_elements;
62 } 63 }
63 64
64 void 65 void
libqpdf/qpdf/QPDF_Array.hh
@@ -35,7 +35,7 @@ class QPDF_Array: public QPDFValue @@ -35,7 +35,7 @@ class QPDF_Array: public QPDFValue
35 void setFromVector(std::vector<std::shared_ptr<QPDFObject>>&& items); 35 void setFromVector(std::vector<std::shared_ptr<QPDFObject>>&& items);
36 bool insert(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 + bool erase(int at);
39 39
40 private: 40 private:
41 QPDF_Array(std::vector<QPDFObjectHandle> const& items); 41 QPDF_Array(std::vector<QPDFObjectHandle> const& items);
qpdf/qtest/qpdf/test88.out
1 WARNING: test array: ignoring attempt to erase out of bounds array item 1 WARNING: test array: ignoring attempt to erase out of bounds array item
  2 +WARNING: minimal.pdf, object 1 0 at offset 19: operation for array attempted on object of type dictionary: ignoring attempt to erase item
2 test 88 done 3 test 88 done
qpdf/test_driver.cc
@@ -3283,6 +3283,7 @@ test_88(QPDF&amp; pdf, char const* arg2) @@ -3283,6 +3283,7 @@ test_88(QPDF&amp; pdf, char const* arg2)
3283 auto arr2 = pdf.getRoot().replaceKeyAndGetNew("/QTest", "[1 2]"_qpdf); 3283 auto arr2 = pdf.getRoot().replaceKeyAndGetNew("/QTest", "[1 2]"_qpdf);
3284 arr2.setObjectDescription(&pdf, "test array"); 3284 arr2.setObjectDescription(&pdf, "test array");
3285 assert(arr2.eraseItemAndGetOld(50).isNull()); 3285 assert(arr2.eraseItemAndGetOld(50).isNull());
  3286 + assert(pdf.getRoot().eraseItemAndGetOld(0).isNull());
3286 } 3287 }
3287 3288
3288 static void 3289 static void