Commit 233e46b55b9e511f5d71f40d6c30aebe7f6ef79c

Authored by m-holger
1 parent 4c65b0a8

Refactor `NNTree::updateIValue`, `getNextKid`, and `increment`: update to use `D…

…ictionary` APIs, replace `getKey` with subscript operator, streamline logic, and simplify bounds checks.
libqpdf/NNTree.cc
@@ -57,21 +57,21 @@ NNTreeIterator::updateIValue(bool allow_invalid) @@ -57,21 +57,21 @@ NNTreeIterator::updateIValue(bool allow_invalid)
57 // we must call updateIValue as well. These cases are handled, and for good measure, we also 57 // we must call updateIValue as well. These cases are handled, and for good measure, we also
58 // call updateIValue in operator* and operator->. 58 // call updateIValue in operator* and operator->.
59 59
  60 + Array items = node[impl.itemsKey()];
  61 + ivalue.first = items[item_number];
  62 + ivalue.second = items[item_number + 1];
  63 + if (ivalue.second) {
  64 + return;
  65 + }
  66 +
60 if (item_number < 0 || !node.isDictionary()) { 67 if (item_number < 0 || !node.isDictionary()) {
61 if (!allow_invalid) { 68 if (!allow_invalid) {
62 throw std::logic_error( 69 throw std::logic_error(
63 "attempt made to dereference an invalid name/number tree iterator"); 70 "attempt made to dereference an invalid name/number tree iterator");
64 } 71 }
65 - ivalue.first = QPDFObjectHandle();  
66 - ivalue.second = QPDFObjectHandle();  
67 return; 72 return;
68 } 73 }
69 - Array items = node.getKey(impl.itemsKey());  
70 - if (!std::cmp_less(item_number + 1, items.size())) {  
71 - impl.error(node, "update ivalue: items array is too short");  
72 - }  
73 - ivalue.first = items[item_number];  
74 - ivalue.second = items[1 + item_number]; 74 + impl.error(node, "update ivalue: items array is too short");
75 } 75 }
76 76
77 NNTreeIterator::PathElement::PathElement(QPDFObjectHandle const& node, int kid_number) : 77 NNTreeIterator::PathElement::PathElement(QPDFObjectHandle const& node, int kid_number) :
@@ -80,24 +80,19 @@ NNTreeIterator::PathElement::PathElement(QPDFObjectHandle const&amp; node, int kid_n @@ -80,24 +80,19 @@ NNTreeIterator::PathElement::PathElement(QPDFObjectHandle const&amp; node, int kid_n
80 { 80 {
81 } 81 }
82 82
83 -QPDFObjectHandle 83 +Dictionary
84 NNTreeIterator::getNextKid(PathElement& pe, bool backward) 84 NNTreeIterator::getNextKid(PathElement& pe, bool backward)
85 { 85 {
86 while (true) { 86 while (true) {
87 pe.kid_number += backward ? -1 : 1; 87 pe.kid_number += backward ? -1 : 1;
88 - Array kids = pe.node.getKey("/Kids");  
89 - if (pe.kid_number >= 0 && std::cmp_less(pe.kid_number, kids.size())) {  
90 - auto result = kids[pe.kid_number];  
91 - if (result.isDictionary() &&  
92 - (result.hasKey("/Kids") || result.hasKey(impl.itemsKey()))) {  
93 - return result;  
94 - } else {  
95 - impl.warn(  
96 - pe.node, "skipping over invalid kid at index " + std::to_string(pe.kid_number));  
97 - }  
98 - } else {  
99 - return QPDFObjectHandle::newNull(); 88 + Dictionary result = pe.node["/Kids"][pe.kid_number];
  89 + if (result.contains("/Kids") || result.contains(impl.itemsKey())) {
  90 + return result;
100 } 91 }
  92 + if (pe.kid_number < 0 || std::cmp_greater_equal(pe.kid_number, pe.node["/Kids"].size())) {
  93 + return {};
  94 + }
  95 + impl.warn(pe.node, "skipping over invalid kid at index " + std::to_string(pe.kid_number));
101 } 96 }
102 } 97 }
103 void 98 void
@@ -110,22 +105,22 @@ NNTreeIterator::increment(bool backward) @@ -110,22 +105,22 @@ NNTreeIterator::increment(bool backward)
110 105
111 while (valid()) { 106 while (valid()) {
112 item_number += backward ? -2 : 2; 107 item_number += backward ? -2 : 2;
113 - Array items = node.getKey(impl.itemsKey()); 108 + Array items = node[impl.itemsKey()];
114 if (item_number < 0 || std::cmp_greater_equal(item_number, items.size())) { 109 if (item_number < 0 || std::cmp_greater_equal(item_number, items.size())) {
115 - bool found = false;  
116 setItemNumber(QPDFObjectHandle(), -1); 110 setItemNumber(QPDFObjectHandle(), -1);
117 - while (!(found || path.empty())) { 111 + while (!path.empty()) {
118 auto& element = path.back(); 112 auto& element = path.back();
119 - auto pe_node = getNextKid(element, backward);  
120 - if (pe_node.null()) {  
121 - path.pop_back(); 113 + if (auto pe_node = getNextKid(element, backward)) {
  114 + if (deepen(pe_node, !backward, false)) {
  115 + break;
  116 + }
122 } else { 117 } else {
123 - found = deepen(pe_node, !backward, false); 118 + path.pop_back();
124 } 119 }
125 } 120 }
126 } 121 }
127 if (item_number >= 0) { 122 if (item_number >= 0) {
128 - items = node.getKey(impl.itemsKey()); 123 + items = node[impl.itemsKey()];
129 if (std::cmp_greater_equal(item_number + 1, items.size())) { 124 if (std::cmp_greater_equal(item_number + 1, items.size())) {
130 impl.warn(node, "items array doesn't have enough elements"); 125 impl.warn(node, "items array doesn't have enough elements");
131 } else if (!impl.keyValid(items[item_number])) { 126 } else if (!impl.keyValid(items[item_number])) {
libqpdf/qpdf/NNTree.hh
@@ -105,7 +105,7 @@ class NNTreeIterator final @@ -105,7 +105,7 @@ class NNTreeIterator final
105 { 105 {
106 path.emplace_back(a_node, kid_number); 106 path.emplace_back(a_node, kid_number);
107 } 107 }
108 - QPDFObjectHandle getNextKid(PathElement& element, bool backward); 108 + qpdf::Dictionary getNextKid(PathElement& element, bool backward);
109 void increment(bool backward); 109 void increment(bool backward);
110 void resetLimits(QPDFObjectHandle node, std::list<PathElement>::iterator parent); 110 void resetLimits(QPDFObjectHandle node, std::list<PathElement>::iterator parent);
111 111