Commit d4a563647ff62e5a01a32ea758de9cadf5a6ca0d
1 parent
32e0bbe4
Refactor `NNTree::deepen`: replace `getKey` with subscript operator for `Array` …
…access, and streamline logic.
Showing
3 changed files
with
37 additions
and
36 deletions
libqpdf/NNTree.cc
| ... | ... | @@ -382,7 +382,7 @@ NNTreeIterator::remove() |
| 382 | 382 | if (!valid()) { |
| 383 | 383 | throw std::logic_error("attempt made to remove an invalid iterator"); |
| 384 | 384 | } |
| 385 | - Array items = node.getKey(impl.itemsKey()); | |
| 385 | + Array items = node[impl.itemsKey()]; | |
| 386 | 386 | int nitems = static_cast<int>(items.size()); |
| 387 | 387 | if (std::cmp_greater(item_number + 2, nitems)) { |
| 388 | 388 | impl.error(node, "found short items array while removing an item"); |
| ... | ... | @@ -429,7 +429,7 @@ NNTreeIterator::remove() |
| 429 | 429 | auto element = lastPathElement(); |
| 430 | 430 | auto parent = element; |
| 431 | 431 | --parent; |
| 432 | - Array kids = element->node.getKey("/Kids"); | |
| 432 | + Array kids = element->node["/Kids"]; | |
| 433 | 433 | kids.erase(element->kid_number); |
| 434 | 434 | auto nkids = kids.size(); |
| 435 | 435 | if (nkids > 0) { |
| ... | ... | @@ -489,14 +489,14 @@ NNTreeIterator::operator==(NNTreeIterator const& other) const |
| 489 | 489 | } |
| 490 | 490 | |
| 491 | 491 | bool |
| 492 | -NNTreeIterator::deepen(QPDFObjectHandle a_node, bool first, bool allow_empty) | |
| 492 | +NNTreeIterator::deepen(Dictionary a_node, bool first, bool allow_empty) | |
| 493 | 493 | { |
| 494 | 494 | // Starting at this node, descend through the first or last kid until we reach a node with |
| 495 | 495 | // items. If we succeed, return true; otherwise return false and leave path alone. |
| 496 | 496 | |
| 497 | 497 | auto opath = path; |
| 498 | 498 | |
| 499 | - auto fail = [this, &opath](QPDFObjectHandle const& failed_node, std::string const& msg) { | |
| 499 | + auto fail = [this, &opath](Dictionary const& failed_node, std::string const& msg) { | |
| 500 | 500 | impl.warn(failed_node, msg); |
| 501 | 501 | path = opath; |
| 502 | 502 | return false; |
| ... | ... | @@ -511,51 +511,52 @@ NNTreeIterator::deepen(QPDFObjectHandle a_node, bool first, bool allow_empty) |
| 511 | 511 | return fail(a_node, "loop detected while traversing name/number tree"); |
| 512 | 512 | } |
| 513 | 513 | |
| 514 | - if (!a_node.isDictionary()) { | |
| 514 | + if (!a_node) { | |
| 515 | 515 | return fail(a_node, "non-dictionary node while traversing name/number tree"); |
| 516 | 516 | } |
| 517 | 517 | |
| 518 | - Array items = a_node.getKey(impl.itemsKey()); | |
| 518 | + Array items = a_node[impl.itemsKey()]; | |
| 519 | 519 | int nitems = static_cast<int>(items.size()); |
| 520 | 520 | if (nitems > 1) { |
| 521 | 521 | setItemNumber(a_node, first ? 0 : nitems - 2); |
| 522 | - break; | |
| 522 | + return true; | |
| 523 | 523 | } |
| 524 | 524 | |
| 525 | - Array kids = a_node.getKey("/Kids"); | |
| 525 | + Array kids = a_node["/Kids"]; | |
| 526 | 526 | int nkids = static_cast<int>(kids.size()); |
| 527 | - if (nkids > 0) { | |
| 528 | - int kid_number = first ? 0 : nkids - 1; | |
| 529 | - addPathElement(a_node, kid_number); | |
| 530 | - auto next = kids[kid_number]; | |
| 531 | - if (!next) { | |
| 532 | - return fail(a_node, "kid number " + std::to_string(kid_number) + " is invalid"); | |
| 527 | + if (nkids == 0) { | |
| 528 | + if (allow_empty && items) { | |
| 529 | + setItemNumber(a_node, -1); | |
| 530 | + return true; | |
| 533 | 531 | } |
| 534 | - if (!next.indirect()) { | |
| 535 | - if (impl.auto_repair) { | |
| 536 | - impl.warn( | |
| 537 | - a_node, | |
| 538 | - "converting kid number " + std::to_string(kid_number) + | |
| 539 | - " to an indirect object"); | |
| 540 | - next = impl.qpdf.makeIndirectObject(next); | |
| 541 | - kids.set(kid_number, next); | |
| 542 | - } else { | |
| 543 | - impl.warn( | |
| 544 | - a_node, | |
| 545 | - "kid number " + std::to_string(kid_number) + " is not an indirect object"); | |
| 546 | - } | |
| 547 | - } | |
| 548 | - a_node = next; | |
| 549 | - } else if (allow_empty && items) { | |
| 550 | - setItemNumber(a_node, -1); | |
| 551 | - break; | |
| 552 | - } else { | |
| 553 | 532 | return fail( |
| 554 | 533 | a_node, |
| 555 | 534 | "name/number tree node has neither non-empty " + impl.itemsKey() + " nor /Kids"); |
| 556 | 535 | } |
| 536 | + | |
| 537 | + int kid_number = first ? 0 : nkids - 1; | |
| 538 | + addPathElement(a_node, kid_number); | |
| 539 | + Dictionary next = kids[kid_number]; | |
| 540 | + if (!next) { | |
| 541 | + return fail(a_node, "kid number " + std::to_string(kid_number) + " is invalid"); | |
| 542 | + } | |
| 543 | + if (!next.indirect()) { | |
| 544 | + if (impl.auto_repair) { | |
| 545 | + impl.warn( | |
| 546 | + a_node, | |
| 547 | + "converting kid number " + std::to_string(kid_number) + | |
| 548 | + " to an indirect object"); | |
| 549 | + next = impl.qpdf.makeIndirectObject(next); | |
| 550 | + kids.set(kid_number, next); | |
| 551 | + } else { | |
| 552 | + impl.warn( | |
| 553 | + a_node, | |
| 554 | + "kid number " + std::to_string(kid_number) + " is not an indirect object"); | |
| 555 | + } | |
| 556 | + } | |
| 557 | + | |
| 558 | + a_node = next; | |
| 557 | 559 | } |
| 558 | - return true; | |
| 559 | 560 | } |
| 560 | 561 | |
| 561 | 562 | NNTreeImpl::iterator | ... | ... |
libqpdf/qpdf/NNTree.hh
| ... | ... | @@ -92,7 +92,7 @@ class NNTreeIterator final |
| 92 | 92 | { |
| 93 | 93 | } |
| 94 | 94 | void updateIValue(bool allow_invalid = true); |
| 95 | - bool deepen(QPDFObjectHandle node, bool first, bool allow_empty); | |
| 95 | + bool deepen(qpdf::Dictionary node, bool first, bool allow_empty); | |
| 96 | 96 | void |
| 97 | 97 | setItemNumber(QPDFObjectHandle const& a_node, int n) |
| 98 | 98 | { | ... | ... |
qpdf/qtest/qpdf/name-tree.out
| ... | ... | @@ -33,7 +33,7 @@ WARNING: name-tree.pdf (Name/Number tree node (object 17)): skipping over invali |
| 33 | 33 | B |
| 34 | 34 | W |
| 35 | 35 | /Bad3 -- invalid kid |
| 36 | -WARNING: name-tree.pdf (Name/Number tree node (object 25)): non-dictionary node while traversing name/number tree | |
| 36 | +WARNING: name-tree.pdf (Name/Number tree node (object 22)): kid number 0 is invalid | |
| 37 | 37 | /Bad4 -- invalid kid |
| 38 | 38 | WARNING: name-tree.pdf (Name/Number tree node (object 23)): attempting to repair after error: name-tree.pdf (Name/Number tree node (object 23)): invalid kid at index 1 |
| 39 | 39 | WARNING: name-tree.pdf (Name/Number tree node (object 23)): skipping over invalid kid at index 1 | ... | ... |