Commit 696802a73e39dbe5ceb456d281ff63f67eca5e14
1 parent
b1d5a928
Add `Array::insert` overload with size_t for consistency, refactor logic, and im…
…prove bounds checking
Showing
2 changed files
with
27 additions
and
21 deletions
libqpdf/QPDF_Array.cc
| @@ -285,43 +285,48 @@ Array::setFromVector(std::vector<QPDFObjectHandle> const& v) | @@ -285,43 +285,48 @@ Array::setFromVector(std::vector<QPDFObjectHandle> const& v) | ||
| 285 | } | 285 | } |
| 286 | 286 | ||
| 287 | bool | 287 | bool |
| 288 | -Array::insert(int at_i, QPDFObjectHandle const& item) | 288 | +Array::insert(size_t at, QPDFObjectHandle const& item) |
| 289 | { | 289 | { |
| 290 | auto a = array(); | 290 | auto a = array(); |
| 291 | size_t sz = size(); | 291 | size_t sz = size(); |
| 292 | - if (at_i < 0) { | ||
| 293 | - return false; | ||
| 294 | - } | ||
| 295 | - size_t at = to_s(at_i); | ||
| 296 | if (at > sz) { | 292 | if (at > sz) { |
| 297 | return false; | 293 | return false; |
| 298 | } | 294 | } |
| 295 | + checkOwnership(item); | ||
| 299 | if (at == sz) { | 296 | if (at == sz) { |
| 300 | // As special case, also allow insert beyond the end | 297 | // As special case, also allow insert beyond the end |
| 301 | push_back(item); | 298 | push_back(item); |
| 302 | return true; | 299 | return true; |
| 303 | } | 300 | } |
| 304 | - checkOwnership(item); | ||
| 305 | - if (a->sp) { | ||
| 306 | - auto iter = a->sp->elements.crbegin(); | ||
| 307 | - while (iter != a->sp->elements.crend()) { | ||
| 308 | - auto key = (iter++)->first; | ||
| 309 | - if (key >= at) { | ||
| 310 | - auto nh = a->sp->elements.extract(key); | ||
| 311 | - ++nh.key(); | ||
| 312 | - a->sp->elements.insert(std::move(nh)); | ||
| 313 | - } else { | ||
| 314 | - break; | ||
| 315 | - } | 301 | + if (!a->sp) { |
| 302 | + a->elements.insert(a->elements.cbegin() + to_i(at), item); | ||
| 303 | + return true; | ||
| 304 | + } | ||
| 305 | + auto iter = a->sp->elements.crbegin(); | ||
| 306 | + while (iter != a->sp->elements.crend()) { | ||
| 307 | + auto key = (iter++)->first; | ||
| 308 | + if (key >= at) { | ||
| 309 | + auto nh = a->sp->elements.extract(key); | ||
| 310 | + ++nh.key(); | ||
| 311 | + a->sp->elements.insert(std::move(nh)); | ||
| 312 | + } else { | ||
| 313 | + break; | ||
| 316 | } | 314 | } |
| 317 | - a->sp->elements[at] = item; | ||
| 318 | - ++a->sp->size; | ||
| 319 | - } else { | ||
| 320 | - a->elements.insert(a->elements.cbegin() + at_i, item); | ||
| 321 | } | 315 | } |
| 316 | + a->sp->elements[at] = item; | ||
| 317 | + ++a->sp->size; | ||
| 322 | return true; | 318 | return true; |
| 323 | } | 319 | } |
| 324 | 320 | ||
| 321 | +bool | ||
| 322 | +Array::insert(int at_i, QPDFObjectHandle const& item) | ||
| 323 | +{ | ||
| 324 | + if (at_i < 0) { | ||
| 325 | + return false; | ||
| 326 | + } | ||
| 327 | + return insert(to_s(at_i), item); | ||
| 328 | +} | ||
| 329 | + | ||
| 325 | void | 330 | void |
| 326 | Array::push_back(QPDFObjectHandle const& item) | 331 | Array::push_back(QPDFObjectHandle const& item) |
| 327 | { | 332 | { |
libqpdf/qpdf/QPDFObjectHandle_private.hh
| @@ -96,6 +96,7 @@ namespace qpdf | @@ -96,6 +96,7 @@ namespace qpdf | ||
| 96 | QPDFObjectHandle get(int n) const; | 96 | QPDFObjectHandle get(int n) const; |
| 97 | bool set(size_t at, QPDFObjectHandle const& oh); | 97 | bool set(size_t at, QPDFObjectHandle const& oh); |
| 98 | bool set(int at, QPDFObjectHandle const& oh); | 98 | bool set(int at, QPDFObjectHandle const& oh); |
| 99 | + bool insert(size_t at, QPDFObjectHandle const& item); | ||
| 99 | bool insert(int at, QPDFObjectHandle const& item); | 100 | bool insert(int at, QPDFObjectHandle const& item); |
| 100 | void push_back(QPDFObjectHandle const& item); | 101 | void push_back(QPDFObjectHandle const& item); |
| 101 | bool erase(int at); | 102 | bool erase(int at); |