Commit 696802a73e39dbe5ceb456d281ff63f67eca5e14

Authored by m-holger
1 parent b1d5a928

Add `Array::insert` overload with size_t for consistency, refactor logic, and im…

…prove bounds checking
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);