summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libqpdf/QPDFObjectHandle.cc9
-rw-r--r--libqpdf/QPDF_Array.cc31
-rw-r--r--libqpdf/SparseOHArray.cc22
-rw-r--r--libqpdf/qpdf/QPDF_Array.hh2
-rw-r--r--qpdf/qpdf.testcov1
-rw-r--r--qpdf/qtest/qpdf/object-types-os.out1
-rw-r--r--qpdf/qtest/qpdf/object-types.out1
-rw-r--r--qpdf/test_driver.cc1
8 files changed, 34 insertions, 34 deletions
diff --git a/libqpdf/QPDFObjectHandle.cc b/libqpdf/QPDFObjectHandle.cc
index 0c4d45ae..fa8b9136 100644
--- a/libqpdf/QPDFObjectHandle.cc
+++ b/libqpdf/QPDFObjectHandle.cc
@@ -932,9 +932,12 @@ QPDFObjectHandle::setArrayFromVector(std::vector<QPDFObjectHandle> const& items)
void
QPDFObjectHandle::insertItem(int at, QPDFObjectHandle const& item)
{
- auto array = asArray();
- if (array) {
- array->insertItem(at, item);
+ if (auto array = asArray()) {
+ if (!array->insert(at, item)) {
+ objectWarning(
+ "ignoring attempt to insert out of bounds array item");
+ QTC::TC("qpdf", "QPDFObjectHandle insert array bounds");
+ }
} else {
typeWarning("array", "ignoring attempt to insert item");
QTC::TC("qpdf", "QPDFObjectHandle array ignoring insert item");
diff --git a/libqpdf/QPDF_Array.cc b/libqpdf/QPDF_Array.cc
index 5a80cdf5..7633266e 100644
--- a/libqpdf/QPDF_Array.cc
+++ b/libqpdf/QPDF_Array.cc
@@ -236,31 +236,24 @@ QPDF_Array::setFromVector(std::vector<std::shared_ptr<QPDFObject>>&& v)
}
}
-void
-QPDF_Array::insertItem(int at, QPDFObjectHandle const& item)
+bool
+QPDF_Array::insert(int at, QPDFObjectHandle const& item)
{
- if (sparse) {
+ int sz = size();
+ if (at < 0 || at > sz) {
// As special case, also allow insert beyond the end
- if ((at < 0) || (at > sp_elements.size())) {
- throw std::logic_error(
- "INTERNAL ERROR: bounds error accessing QPDF_Array element");
- }
- sp_elements.insert(at, item);
+ return false;
+ } else if (at == sz) {
+ push_back(item);
} else {
- // As special case, also allow insert beyond the end
- size_t idx = QIntC::to_size(at);
- if ((at < 0) || (at > QIntC::to_int(elements.size()))) {
- throw std::logic_error(
- "INTERNAL ERROR: bounds error accessing QPDF_Array element");
- }
- if (idx == elements.size()) {
- // Allow inserting to the last position
- elements.push_back(item.getObj());
+ checkOwnership(item);
+ if (sparse) {
+ sp_elements.insert(at, item);
} else {
- int n = int(idx);
- elements.insert(elements.cbegin() + n, item.getObj());
+ elements.insert(elements.cbegin() + at, item.getObj());
}
}
+ return true;
}
void
diff --git a/libqpdf/SparseOHArray.cc b/libqpdf/SparseOHArray.cc
index 48716deb..8f6c02d7 100644
--- a/libqpdf/SparseOHArray.cc
+++ b/libqpdf/SparseOHArray.cc
@@ -64,23 +64,23 @@ SparseOHArray::erase(int idx)
void
SparseOHArray::insert(int idx, QPDFObjectHandle oh)
{
- if (idx > this->n_elements) {
- throw std::logic_error("bounds error inserting item to SparseOHArray");
- } else if (idx == this->n_elements) {
+ if (idx == n_elements) {
// Allow inserting to the last position
append(oh);
} else {
- decltype(this->elements) dest;
- for (auto const& iter: this->elements) {
- if (iter.first < idx) {
- dest.insert(iter);
+ auto iter = elements.crbegin();
+ while (iter != elements.crend()) {
+ auto key = (iter++)->first;
+ if (key >= idx) {
+ auto nh = elements.extract(key);
+ ++nh.key();
+ elements.insert(std::move(nh));
} else {
- dest[iter.first + 1] = iter.second;
+ break;
}
}
- this->elements = dest;
- this->elements[idx] = oh.getObj();
- ++this->n_elements;
+ elements[idx] = oh.getObj();
+ ++n_elements;
}
}
diff --git a/libqpdf/qpdf/QPDF_Array.hh b/libqpdf/qpdf/QPDF_Array.hh
index 61f14d0f..8768c9ad 100644
--- a/libqpdf/qpdf/QPDF_Array.hh
+++ b/libqpdf/qpdf/QPDF_Array.hh
@@ -33,7 +33,7 @@ class QPDF_Array: public QPDFValue
void setItem(int, QPDFObjectHandle const&);
void setFromVector(std::vector<QPDFObjectHandle> const& items);
void setFromVector(std::vector<std::shared_ptr<QPDFObject>>&& items);
- void insertItem(int at, QPDFObjectHandle const& item);
+ bool insert(int at, QPDFObjectHandle const& item);
void push_back(QPDFObjectHandle const& item);
void eraseItem(int at);
diff --git a/qpdf/qpdf.testcov b/qpdf/qpdf.testcov
index cad67565..736c02b4 100644
--- a/qpdf/qpdf.testcov
+++ b/qpdf/qpdf.testcov
@@ -305,6 +305,7 @@ QPDFObjectHandle array treating as empty vector 0
QPDFObjectHandle array ignoring set item 0
QPDFObjectHandle array ignoring replace items 0
QPDFObjectHandle array ignoring insert item 0
+QPDFObjectHandle insert array bounds 0
QPDFObjectHandle array ignoring append item 0
QPDFObjectHandle array ignoring erase item 0
QPDFObjectHandle dictionary false for hasKey 0
diff --git a/qpdf/qtest/qpdf/object-types-os.out b/qpdf/qtest/qpdf/object-types-os.out
index a95fa4d8..1ba84d50 100644
--- a/qpdf/qtest/qpdf/object-types-os.out
+++ b/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
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
WARNING: object-types-os.pdf object stream 1, object 7 0 at offset 384: ignoring attempt to erase out of bounds array item
WARNING: object-types-os.pdf object stream 1, object 7 0 at offset 384: ignoring attempt to erase out of bounds array item
+WARNING: object-types-os.pdf object stream 1, object 7 0 at offset 384: ignoring attempt to insert out of bounds array item
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
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
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
diff --git a/qpdf/qtest/qpdf/object-types.out b/qpdf/qtest/qpdf/object-types.out
index 718105db..bf41044e 100644
--- a/qpdf/qtest/qpdf/object-types.out
+++ b/qpdf/qtest/qpdf/object-types.out
@@ -5,6 +5,7 @@ WARNING: object-types.pdf, object 8 0 at offset 669: operation for array attempt
WARNING: object-types.pdf, object 8 0 at offset 669: operation for array attempted on object of type integer: ignoring attempt to append item
WARNING: object-types.pdf, object 8 0 at offset 717: ignoring attempt to erase out of bounds array item
WARNING: object-types.pdf, object 8 0 at offset 717: ignoring attempt to erase out of bounds array item
+WARNING: object-types.pdf, object 8 0 at offset 717: ignoring attempt to insert out of bounds array item
WARNING: object-types.pdf, object 8 0 at offset 669: operation for array attempted on object of type integer: ignoring attempt to erase item
WARNING: object-types.pdf, object 8 0 at offset 669: operation for array attempted on object of type integer: ignoring attempt to insert item
WARNING: object-types.pdf, object 8 0 at offset 669: operation for array attempted on object of type integer: ignoring attempt to replace items
diff --git a/qpdf/test_driver.cc b/qpdf/test_driver.cc
index 5bae8b54..8c54ad01 100644
--- a/qpdf/test_driver.cc
+++ b/qpdf/test_driver.cc
@@ -1506,6 +1506,7 @@ test_42(QPDF& pdf, char const* arg2)
integer.appendItem(null);
array.eraseItem(-1);
array.eraseItem(16059);
+ array.insertItem(42, "/Dontpanic"_qpdf);
integer.eraseItem(0);
integer.insertItem(0, null);
integer.setArrayFromVector(std::vector<QPDFObjectHandle>());