Commit 12837f14b6c793313778ca13ca3f8e615d41117b
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 | 112 | |
| 113 | 113 | case QPDFTokenizer::tt_array_close: |
| 114 | 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 | 129 | } else { |
| 117 | 130 | QTC::TC("qpdf", "QPDFParser bad array close"); |
| 118 | 131 | warn("treating unexpected array close token as null"); |
| ... | ... | @@ -273,11 +286,11 @@ QPDFParser::parse(bool& empty, bool content_stream) |
| 273 | 286 | if (is_null) { |
| 274 | 287 | object = null_oh; |
| 275 | 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 | 290 | setDescription(object, input->getLastOffset()); |
| 278 | 291 | } |
| 279 | 292 | set_offset = true; |
| 280 | - olist.push_back(object); | |
| 293 | + stack.back().olist.push_back(object); | |
| 281 | 294 | break; |
| 282 | 295 | |
| 283 | 296 | case st_top: |
| ... | ... | @@ -294,15 +307,7 @@ QPDFParser::parse(bool& empty, bool content_stream) |
| 294 | 307 | } |
| 295 | 308 | parser_state_e old_state = state_stack.back(); |
| 296 | 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 | 311 | // Convert list to map. Alternating elements are keys. Attempt to recover more or |
| 307 | 312 | // less gracefully from invalid dictionaries. |
| 308 | 313 | std::set<std::string> names; | ... | ... |