Commit 1285f9767af983df74b52c4f2aadcbfaec36a6fc
1 parent
605b1429
Add new method QPDFParser::fixMissingKeys
Showing
2 changed files
with
30 additions
and
26 deletions
libqpdf/QPDFParser.cc
| @@ -244,8 +244,8 @@ QPDFParser::parseRemainder(bool content_stream) | @@ -244,8 +244,8 @@ QPDFParser::parseRemainder(bool content_stream) | ||
| 244 | case QPDFTokenizer::tt_dict_close: | 244 | case QPDFTokenizer::tt_dict_close: |
| 245 | if (frame->state <= st_dictionary_value) { | 245 | if (frame->state <= st_dictionary_value) { |
| 246 | // Attempt to recover more or less gracefully from invalid dictionaries. | 246 | // Attempt to recover more or less gracefully from invalid dictionaries. |
| 247 | - | ||
| 248 | auto& dict = frame->dict; | 247 | auto& dict = frame->dict; |
| 248 | + | ||
| 249 | if (frame->state == st_dictionary_value) { | 249 | if (frame->state == st_dictionary_value) { |
| 250 | QTC::TC("qpdf", "QPDFParser no val for last key"); | 250 | QTC::TC("qpdf", "QPDFParser no val for last key"); |
| 251 | warn( | 251 | warn( |
| @@ -254,31 +254,8 @@ QPDFParser::parseRemainder(bool content_stream) | @@ -254,31 +254,8 @@ QPDFParser::parseRemainder(bool content_stream) | ||
| 254 | dict[frame->key] = QPDF_Null::create(); | 254 | dict[frame->key] = QPDF_Null::create(); |
| 255 | } | 255 | } |
| 256 | 256 | ||
| 257 | - if (!frame->olist.empty()) { | ||
| 258 | - std::set<std::string> names; | ||
| 259 | - for (auto& obj: frame->olist) { | ||
| 260 | - if (obj->getTypeCode() == ::ot_name) { | ||
| 261 | - names.insert(obj->getStringValue()); | ||
| 262 | - } | ||
| 263 | - } | ||
| 264 | - int next_fake_key = 1; | ||
| 265 | - for (auto const& item: frame->olist) { | ||
| 266 | - while (true) { | ||
| 267 | - const std::string key = "/QPDFFake" + std::to_string(next_fake_key++); | ||
| 268 | - const bool found_fake = (dict.count(key) == 0 && names.count(key) == 0); | ||
| 269 | - QTC::TC("qpdf", "QPDFParser found fake", (found_fake ? 0 : 1)); | ||
| 270 | - if (found_fake) { | ||
| 271 | - warn( | ||
| 272 | - frame->offset, | ||
| 273 | - "expected dictionary key but found non-name object; inserting " | ||
| 274 | - "key " + | ||
| 275 | - key); | ||
| 276 | - dict[key] = item; | ||
| 277 | - break; | ||
| 278 | - } | ||
| 279 | - } | ||
| 280 | - } | ||
| 281 | - } | 257 | + if (!frame->olist.empty()) |
| 258 | + fixMissingKeys(); | ||
| 282 | 259 | ||
| 283 | if (!frame->contents_string.empty() && dict.count("/Type") && | 260 | if (!frame->contents_string.empty() && dict.count("/Type") && |
| 284 | dict["/Type"].isNameAndEquals("/Sig") && dict.count("/ByteRange") && | 261 | dict["/Type"].isNameAndEquals("/Sig") && dict.count("/ByteRange") && |
| @@ -466,6 +443,32 @@ QPDFParser::setDescription(ObjectPtr& obj, qpdf_offset_t parsed_offset) | @@ -466,6 +443,32 @@ QPDFParser::setDescription(ObjectPtr& obj, qpdf_offset_t parsed_offset) | ||
| 466 | } | 443 | } |
| 467 | } | 444 | } |
| 468 | 445 | ||
| 446 | +void | ||
| 447 | +QPDFParser::fixMissingKeys() | ||
| 448 | +{ | ||
| 449 | + std::set<std::string> names; | ||
| 450 | + for (auto& obj: frame->olist) { | ||
| 451 | + if (obj->getTypeCode() == ::ot_name) { | ||
| 452 | + names.insert(obj->getStringValue()); | ||
| 453 | + } | ||
| 454 | + } | ||
| 455 | + int next_fake_key = 1; | ||
| 456 | + for (auto const& item: frame->olist) { | ||
| 457 | + while (true) { | ||
| 458 | + const std::string key = "/QPDFFake" + std::to_string(next_fake_key++); | ||
| 459 | + const bool found_fake = frame->dict.count(key) == 0 && names.count(key) == 0; | ||
| 460 | + QTC::TC("qpdf", "QPDFParser found fake", (found_fake ? 0 : 1)); | ||
| 461 | + if (found_fake) { | ||
| 462 | + warn( | ||
| 463 | + frame->offset, | ||
| 464 | + "expected dictionary key but found non-name object; inserting key " + key); | ||
| 465 | + frame->dict[key] = item; | ||
| 466 | + break; | ||
| 467 | + } | ||
| 468 | + } | ||
| 469 | + } | ||
| 470 | +} | ||
| 471 | + | ||
| 469 | bool | 472 | bool |
| 470 | QPDFParser::tooManyBadTokens() | 473 | QPDFParser::tooManyBadTokens() |
| 471 | { | 474 | { |
libqpdf/qpdf/QPDFParser.hh
| @@ -61,6 +61,7 @@ class QPDFParser | @@ -61,6 +61,7 @@ class QPDFParser | ||
| 61 | void addScalar(Args&&... args); | 61 | void addScalar(Args&&... args); |
| 62 | bool tooManyBadTokens(); | 62 | bool tooManyBadTokens(); |
| 63 | void warnDuplicateKey(); | 63 | void warnDuplicateKey(); |
| 64 | + void fixMissingKeys(); | ||
| 64 | void warn(qpdf_offset_t offset, std::string const& msg) const; | 65 | void warn(qpdf_offset_t offset, std::string const& msg) const; |
| 65 | void warn(std::string const& msg) const; | 66 | void warn(std::string const& msg) const; |
| 66 | void warn(QPDFExc const&) const; | 67 | void warn(QPDFExc const&) const; |