Commit 12837f14b6c793313778ca13ca3f8e615d41117b

Authored by m-holger
1 parent 26e0bf46

In QPDFParser::parse refactor handling of array_close tokens

Showing 1 changed file with 17 additions and 12 deletions
libqpdf/QPDFParser.cc
@@ -112,7 +112,20 @@ QPDFParser::parse(bool& empty, bool content_stream) @@ -112,7 +112,20 @@ QPDFParser::parse(bool& empty, bool content_stream)
112 112
113 case QPDFTokenizer::tt_array_close: 113 case QPDFTokenizer::tt_array_close:
114 if (state == st_array) { 114 if (state == st_array) {
115 - state = st_stop; 115 + if ((state_stack.size() < 2) || (stack.size() < 2)) {
  116 + throw std::logic_error("QPDFParser::parseInternal: st_stop encountered with "
  117 + "insufficient elements in stack");
  118 + }
  119 + object = QPDF_Array::create(std::move(olist), frame.null_count > 100);
  120 + setDescription(object, offset - 1);
  121 + // The `offset` points to the next of "[". Set the rewind offset to point to the
  122 + // beginning of "[". This has been explicitly tested with whitespace surrounding the
  123 + // array start delimiter. getLastOffset points to the array end token and therefore
  124 + // can't be used here.
  125 + set_offset = true;
  126 + state_stack.pop_back();
  127 + state = state_stack.back();
  128 + stack.pop_back();
116 } else { 129 } else {
117 QTC::TC("qpdf", "QPDFParser bad array close"); 130 QTC::TC("qpdf", "QPDFParser bad array close");
118 warn("treating unexpected array close token as null"); 131 warn("treating unexpected array close token as null");
@@ -273,11 +286,11 @@ QPDFParser::parse(bool&amp; empty, bool content_stream) @@ -273,11 +286,11 @@ QPDFParser::parse(bool&amp; empty, bool content_stream)
273 if (is_null) { 286 if (is_null) {
274 object = null_oh; 287 object = null_oh;
275 // No need to set description for direct nulls - they probably will become implicit. 288 // No need to set description for direct nulls - they probably will become implicit.
276 - } else if (!indirect_ref) { 289 + } else if (!indirect_ref && !set_offset) {
277 setDescription(object, input->getLastOffset()); 290 setDescription(object, input->getLastOffset());
278 } 291 }
279 set_offset = true; 292 set_offset = true;
280 - olist.push_back(object); 293 + stack.back().olist.push_back(object);
281 break; 294 break;
282 295
283 case st_top: 296 case st_top:
@@ -294,15 +307,7 @@ QPDFParser::parse(bool&amp; empty, bool content_stream) @@ -294,15 +307,7 @@ QPDFParser::parse(bool&amp; empty, bool content_stream)
294 } 307 }
295 parser_state_e old_state = state_stack.back(); 308 parser_state_e old_state = state_stack.back();
296 state_stack.pop_back(); 309 state_stack.pop_back();
297 - if (old_state == st_array) {  
298 - object = QPDF_Array::create(std::move(olist), frame.null_count > 100);  
299 - setDescription(object, offset - 1);  
300 - // The `offset` points to the next of "[". Set the rewind offset to point to the  
301 - // beginning of "[". This has been explicitly tested with whitespace surrounding the  
302 - // array start delimiter. getLastOffset points to the array end token and therefore  
303 - // can't be used here.  
304 - set_offset = true;  
305 - } else if (old_state == st_dictionary) { 310 + if (old_state == st_dictionary) {
306 // Convert list to map. Alternating elements are keys. Attempt to recover more or 311 // Convert list to map. Alternating elements are keys. Attempt to recover more or
307 // less gracefully from invalid dictionaries. 312 // less gracefully from invalid dictionaries.
308 std::set<std::string> names; 313 std::set<std::string> names;