Commit 3f567ae02da70f5634d728d2d089e04a4f2fad56

Authored by m-holger
Committed by Jay Berkenbilt
1 parent d67a54ae

Refactor dictionary processing loop in QPDFParser::parse

Showing 1 changed file with 27 additions and 28 deletions
libqpdf/QPDFParser.cc
@@ -344,24 +344,21 @@ QPDFParser::parse(bool& empty, bool content_stream) @@ -344,24 +344,21 @@ QPDFParser::parse(bool& empty, bool content_stream)
344 if (obj->getTypeCode() == ::ot_name) { 344 if (obj->getTypeCode() == ::ot_name) {
345 names.insert(obj->getStringValue()); 345 names.insert(obj->getStringValue());
346 } 346 }
347 - } else {  
348 - obj = null_oh;  
349 } 347 }
350 } 348 }
351 349
352 std::map<std::string, QPDFObjectHandle> dict; 350 std::map<std::string, QPDFObjectHandle> dict;
353 int next_fake_key = 1; 351 int next_fake_key = 1;
354 - size_t n_elements = olist.size();  
355 - for (unsigned int i = 0; i < n_elements; ++i) {  
356 - QPDFObjectHandle key_obj = olist.at(i);  
357 - QPDFObjectHandle val;  
358 - if (key_obj.isIndirect() || (!key_obj.isName())) {  
359 - bool found_fake = false;  
360 - std::string candidate;  
361 - while (!found_fake) {  
362 - candidate =  
363 - "/QPDFFake" + std::to_string(next_fake_key++);  
364 - found_fake = (names.count(candidate) == 0); 352 + for (auto iter = olist.begin(); iter != olist.end();) {
  353 + // Calculate key.
  354 + std::string key;
  355 + if (*iter && (*iter)->getTypeCode() == ::ot_name) {
  356 + key = (*iter)->getStringValue();
  357 + ++iter;
  358 + } else {
  359 + for (bool found_fake = false; !found_fake;) {
  360 + key = "/QPDFFake" + std::to_string(next_fake_key++);
  361 + found_fake = (names.count(key) == 0);
365 QTC::TC( 362 QTC::TC(
366 "qpdf", 363 "qpdf",
367 "QPDFParser found fake", 364 "QPDFParser found fake",
@@ -371,21 +368,8 @@ QPDFParser::parse(bool&amp; empty, bool content_stream) @@ -371,21 +368,8 @@ QPDFParser::parse(bool&amp; empty, bool content_stream)
371 offset, 368 offset,
372 "expected dictionary key but found" 369 "expected dictionary key but found"
373 " non-name object; inserting key " + 370 " non-name object; inserting key " +
374 - candidate);  
375 - val = key_obj;  
376 - key_obj = QPDFObjectHandle::newName(candidate);  
377 - } else if (i + 1 >= olist.size()) {  
378 - QTC::TC("qpdf", "QPDFParser no val for last key");  
379 - warn(  
380 - offset,  
381 - "dictionary ended prematurely; "  
382 - "using null as value for last key");  
383 - val = QPDFObjectHandle::newNull();  
384 - setDescription(val.obj, offset);  
385 - } else {  
386 - val = olist.at(++i); 371 + key);
387 } 372 }
388 - std::string key = key_obj.getName();  
389 if (dict.count(key) > 0) { 373 if (dict.count(key) > 0) {
390 QTC::TC("qpdf", "QPDFParser duplicate dict key"); 374 QTC::TC("qpdf", "QPDFParser duplicate dict key");
391 warn( 375 warn(
@@ -394,7 +378,22 @@ QPDFParser::parse(bool&amp; empty, bool content_stream) @@ -394,7 +378,22 @@ QPDFParser::parse(bool&amp; empty, bool content_stream)
394 "; last occurrence overrides earlier " 378 "; last occurrence overrides earlier "
395 "ones"); 379 "ones");
396 } 380 }
397 - dict[key] = val; 381 +
  382 + // Calculate value.
  383 + std::shared_ptr<QPDFObject> val;
  384 + if (iter != olist.end()) {
  385 + val = *iter ? *iter : QPDF_Null::create();
  386 + ++iter;
  387 + } else {
  388 + QTC::TC("qpdf", "QPDFParser no val for last key");
  389 + warn(
  390 + offset,
  391 + "dictionary ended prematurely; "
  392 + "using null as value for last key");
  393 + val = QPDF_Null::create();
  394 + }
  395 +
  396 + dict[std::move(key)] = std::move(val);
398 } 397 }
399 if (!frame.contents_string.empty() && dict.count("/Type") && 398 if (!frame.contents_string.empty() && dict.count("/Type") &&
400 dict["/Type"].isNameAndEquals("/Sig") && 399 dict["/Type"].isNameAndEquals("/Sig") &&