Commit 01dbae428d7c856a1a63625e15912ceddbf6eb67
1 parent
cabd582e
Refactor `replaceForeignIndirectObjects`: simplify object replacement logic, str…
…eamline type-specific handling, and remove redundant test coverage evaluations.
Showing
2 changed files
with
31 additions
and
36 deletions
libqpdf/QPDF.cc
| ... | ... | @@ -609,53 +609,53 @@ QPDFObjectHandle |
| 609 | 609 | QPDF::replaceForeignIndirectObjects(QPDFObjectHandle foreign, ObjCopier& obj_copier, bool top) |
| 610 | 610 | { |
| 611 | 611 | auto foreign_tc = foreign.getTypeCode(); |
| 612 | - QPDFObjectHandle result; | |
| 613 | - if ((!top) && foreign.isIndirect()) { | |
| 614 | - QTC::TC("qpdf", "QPDF replace indirect"); | |
| 615 | - auto mapping = obj_copier.object_map.find(foreign.getObjGen()); | |
| 612 | + | |
| 613 | + if (!top && foreign.indirect()) { | |
| 614 | + auto mapping = obj_copier.object_map.find(foreign.id_gen()); | |
| 616 | 615 | if (mapping == obj_copier.object_map.end()) { |
| 617 | 616 | // This case would occur if this is a reference to a Pages object that we didn't |
| 618 | 617 | // traverse into. |
| 619 | - QTC::TC("qpdf", "QPDF replace foreign indirect with null"); | |
| 620 | - result = QPDFObjectHandle::newNull(); | |
| 621 | - } else { | |
| 622 | - result = mapping->second; | |
| 618 | + return QPDFObjectHandle::newNull(); | |
| 623 | 619 | } |
| 624 | - } else if (foreign_tc == ::ot_array) { | |
| 625 | - QTC::TC("qpdf", "QPDF replace array"); | |
| 626 | - result = QPDFObjectHandle::newArray(); | |
| 627 | - for (auto const& item: foreign.as_array()) { | |
| 628 | - result.appendItem(replaceForeignIndirectObjects(item, obj_copier, false)); | |
| 620 | + return mapping->second; | |
| 621 | + } | |
| 622 | + | |
| 623 | + if (foreign_tc == ::ot_array) { | |
| 624 | + Array array = foreign; | |
| 625 | + std::vector<QPDFObjectHandle> result; | |
| 626 | + result.reserve(array.size()); | |
| 627 | + for (auto const& item: array) { | |
| 628 | + result.emplace_back(replaceForeignIndirectObjects(item, obj_copier, false)); | |
| 629 | 629 | } |
| 630 | - } else if (foreign_tc == ::ot_dictionary) { | |
| 631 | - QTC::TC("qpdf", "QPDF replace dictionary"); | |
| 632 | - result = QPDFObjectHandle::newDictionary(); | |
| 633 | - for (auto const& [key, value]: foreign.as_dictionary()) { | |
| 630 | + return Array(std::move(result)); | |
| 631 | + } | |
| 632 | + | |
| 633 | + if (foreign_tc == ::ot_dictionary) { | |
| 634 | + auto result = Dictionary::empty(); | |
| 635 | + for (auto const& [key, value]: Dictionary(foreign)) { | |
| 634 | 636 | if (!value.null()) { |
| 635 | 637 | result.replaceKey(key, replaceForeignIndirectObjects(value, obj_copier, false)); |
| 636 | 638 | } |
| 637 | 639 | } |
| 638 | - } else if (foreign_tc == ::ot_stream) { | |
| 639 | - QTC::TC("qpdf", "QPDF replace stream"); | |
| 640 | - result = obj_copier.object_map[foreign.getObjGen()]; | |
| 641 | - QPDFObjectHandle dict = result.getDict(); | |
| 642 | - QPDFObjectHandle old_dict = foreign.getDict(); | |
| 643 | - for (auto const& [key, value]: old_dict.as_dictionary()) { | |
| 640 | + return result; | |
| 641 | + } | |
| 642 | + | |
| 643 | + if (foreign_tc == ::ot_stream) { | |
| 644 | + Stream stream = foreign; | |
| 645 | + Stream result = obj_copier.object_map[foreign]; | |
| 646 | + auto dict = result.getDict(); | |
| 647 | + for (auto const& [key, value]: stream.getDict()) { | |
| 644 | 648 | if (!value.null()) { |
| 645 | 649 | dict.replaceKey(key, replaceForeignIndirectObjects(value, obj_copier, false)); |
| 646 | 650 | } |
| 647 | 651 | } |
| 648 | 652 | copyStreamData(result, foreign); |
| 649 | - } else { | |
| 650 | - foreign.assertScalar(); | |
| 651 | - result = foreign; | |
| 652 | - result.makeDirect(); | |
| 653 | - } | |
| 654 | - | |
| 655 | - if (top && (!result.isStream()) && result.isIndirect()) { | |
| 656 | - throw std::logic_error("replacement for foreign object is indirect"); | |
| 653 | + return result; | |
| 657 | 654 | } |
| 658 | 655 | |
| 656 | + foreign.assertScalar(); | |
| 657 | + auto result = foreign; | |
| 658 | + result.makeDirect(); | |
| 659 | 659 | return result; |
| 660 | 660 | } |
| 661 | 661 | ... | ... |
qpdf/qpdf.testcov
| ... | ... | @@ -126,11 +126,6 @@ QPDF_Stream unknown stream length 0 |
| 126 | 126 | QPDF replaceReserved 0 |
| 127 | 127 | QPDF copyForeign direct 0 |
| 128 | 128 | QPDF copyForeign not foreign 0 |
| 129 | -QPDF replace indirect 0 | |
| 130 | -QPDF replace array 0 | |
| 131 | -QPDF replace dictionary 0 | |
| 132 | -QPDF replace stream 0 | |
| 133 | -QPDF replace foreign indirect with null 0 | |
| 134 | 129 | QPDFWriter copy use_aes 1 |
| 135 | 130 | QPDFParser indirect without context 0 |
| 136 | 131 | QPDFObjectHandle trailing data in parse 0 | ... | ... |