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 | 285 | } |
| 286 | 286 | |
| 287 | 287 | bool |
| 288 | -Array::insert(int at_i, QPDFObjectHandle const& item) | |
| 288 | +Array::insert(size_t at, QPDFObjectHandle const& item) | |
| 289 | 289 | { |
| 290 | 290 | auto a = array(); |
| 291 | 291 | size_t sz = size(); |
| 292 | - if (at_i < 0) { | |
| 293 | - return false; | |
| 294 | - } | |
| 295 | - size_t at = to_s(at_i); | |
| 296 | 292 | if (at > sz) { |
| 297 | 293 | return false; |
| 298 | 294 | } |
| 295 | + checkOwnership(item); | |
| 299 | 296 | if (at == sz) { |
| 300 | 297 | // As special case, also allow insert beyond the end |
| 301 | 298 | push_back(item); |
| 302 | 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 | 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 | 330 | void |
| 326 | 331 | Array::push_back(QPDFObjectHandle const& item) |
| 327 | 332 | { | ... | ... |
libqpdf/qpdf/QPDFObjectHandle_private.hh
| ... | ... | @@ -96,6 +96,7 @@ namespace qpdf |
| 96 | 96 | QPDFObjectHandle get(int n) const; |
| 97 | 97 | bool set(size_t at, QPDFObjectHandle const& oh); |
| 98 | 98 | bool set(int at, QPDFObjectHandle const& oh); |
| 99 | + bool insert(size_t at, QPDFObjectHandle const& item); | |
| 99 | 100 | bool insert(int at, QPDFObjectHandle const& item); |
| 100 | 101 | void push_back(QPDFObjectHandle const& item); |
| 101 | 102 | bool erase(int at); | ... | ... |