Commit 0d8b0882eaba9288501a7f1d96474b542f714199

Authored by m-holger
1 parent baa77f54

Refactor `NNTree::deepen`: introduce lambda for failure handling, simplify loop …

…logic, and replace redundant code with subscript operators.
libqpdf/NNTree.cc
... ... @@ -592,74 +592,64 @@ NNTreeIterator::deepen(QPDFObjectHandle a_node, bool first, bool allow_empty)
592 592 // items. If we succeed, return true; otherwise return false and leave path alone.
593 593  
594 594 auto opath = path;
595   - bool failed = false;
  595 +
  596 + auto fail = [this, &opath](QPDFObjectHandle const& failed_node, std::string const& msg) {
  597 + impl.warn(failed_node, msg);
  598 + path = opath;
  599 + return false;
  600 + };
596 601  
597 602 QPDFObjGen::set seen;
598 603 for (auto const& i: path) {
599 604 seen.add(i.node);
600 605 }
601   - while (!failed) {
  606 + while (true) {
602 607 if (!seen.add(a_node)) {
603   - QTC::TC("qpdf", "NNTree deepen: loop");
604   - impl.warn(a_node, "loop detected while traversing name/number tree");
605   - failed = true;
606   - break;
  608 + return fail(a_node, "loop detected while traversing name/number tree");
607 609 }
608 610  
609 611 if (!a_node.isDictionary()) {
610   - QTC::TC("qpdf", "NNTree node is not a dictionary");
611   - impl.warn(a_node, "non-dictionary node while traversing name/number tree");
612   - failed = true;
613   - break;
  612 + return fail(a_node, "non-dictionary node while traversing name/number tree");
614 613 }
615 614  
616   - auto kids = a_node.getKey("/Kids");
617   - int nkids = kids.isArray() ? kids.getArrayNItems() : 0;
618 615 auto items = a_node.getKey(impl.details.itemsKey());
619   - int nitems = items.isArray() ? items.getArrayNItems() : 0;
620   - if (nitems > 0) {
  616 + int nitems = static_cast<int>(items.size());
  617 + if (nitems > 1) {
621 618 setItemNumber(a_node, first ? 0 : nitems - 2);
622 619 break;
623   - } else if (nkids > 0) {
  620 + }
  621 +
  622 + auto kids = a_node.getKey("/Kids");
  623 + int nkids = kids.isArray() ? static_cast<int>(kids.size()) : 0;
  624 + if (nkids > 0) {
624 625 int kid_number = first ? 0 : nkids - 1;
625 626 addPathElement(a_node, kid_number);
626   - auto next = kids.getArrayItem(kid_number);
  627 + auto next = kids[kid_number];
627 628 if (!next.isIndirect()) {
628 629 if (impl.auto_repair) {
629   - QTC::TC("qpdf", "NNTree fix indirect kid");
630 630 impl.warn(
631 631 a_node,
632   - ("converting kid number " + std::to_string(kid_number) +
633   - " to an indirect object"));
  632 + "converting kid number " + std::to_string(kid_number) +
  633 + " to an indirect object");
634 634 next = impl.qpdf.makeIndirectObject(next);
635 635 kids.setArrayItem(kid_number, next);
636 636 } else {
637   - QTC::TC("qpdf", "NNTree warn indirect kid");
638 637 impl.warn(
639 638 a_node,
640   - ("kid number " + std::to_string(kid_number) +
641   - " is not an indirect object"));
  639 + "kid number " + std::to_string(kid_number) + " is not an indirect object");
642 640 }
643 641 }
644 642 a_node = next;
645 643 } else if (allow_empty && items.isArray()) {
646   - QTC::TC("qpdf", "NNTree deepen found empty");
647 644 setItemNumber(a_node, -1);
648 645 break;
649 646 } else {
650   - QTC::TC("qpdf", "NNTree deepen: invalid node");
651   - impl.warn(
  647 + return fail(
652 648 a_node,
653   - ("name/number tree node has neither non-empty " + impl.details.itemsKey() +
654   - " nor /Kids"));
655   - failed = true;
656   - break;
  649 + "name/number tree node has neither non-empty " + impl.details.itemsKey() +
  650 + " nor /Kids");
657 651 }
658 652 }
659   - if (failed) {
660   - path = opath;
661   - return false;
662   - }
663 653 return true;
664 654 }
665 655  
... ...
qpdf/qpdf.testcov
... ... @@ -519,15 +519,10 @@ qpdf-c called qpdf_oh_unparse_resolved 0
519 519 qpdf-c called qpdf_oh_unparse_binary 0
520 520 QPDFWriter getFilterOnWrite false 0
521 521 QPDFPageObjectHelper::forEachXObject 3
522   -NNTree deepen: invalid node 0
523   -NNTree deepen: loop 0
524 522 NNTree skip invalid kid 0
525 523 NNTree skip item at end of short items 0
526 524 NNTree skip invalid key 0
527   -NNTree deepen found empty 0
528 525 NNTree unable to determine limits 0
529   -NNTree warn indirect kid 0
530   -NNTree fix indirect kid 0
531 526 NNTree repair 0
532 527 NNTree split root + leaf 0
533 528 NNTree split root + !leaf 0
... ... @@ -536,7 +531,6 @@ NNTree split items 0
536 531 NNTree split second half item 0
537 532 NNTree split parent 0
538 533 NNTree split second half kid 0
539   -NNTree node is not a dictionary 0
540 534 NNTree limits didn't change 0
541 535 NNTree increment end() 0
542 536 NNTree insertAfter inserts first 0
... ...