Commit 01dbae428d7c856a1a63625e15912ceddbf6eb67

Authored by m-holger
1 parent cabd582e

Refactor `replaceForeignIndirectObjects`: simplify object replacement logic, str…

…eamline type-specific handling, and remove redundant test coverage evaluations.
libqpdf/QPDF.cc
@@ -609,53 +609,53 @@ QPDFObjectHandle @@ -609,53 +609,53 @@ QPDFObjectHandle
609 QPDF::replaceForeignIndirectObjects(QPDFObjectHandle foreign, ObjCopier& obj_copier, bool top) 609 QPDF::replaceForeignIndirectObjects(QPDFObjectHandle foreign, ObjCopier& obj_copier, bool top)
610 { 610 {
611 auto foreign_tc = foreign.getTypeCode(); 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 if (mapping == obj_copier.object_map.end()) { 615 if (mapping == obj_copier.object_map.end()) {
617 // This case would occur if this is a reference to a Pages object that we didn't 616 // This case would occur if this is a reference to a Pages object that we didn't
618 // traverse into. 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 if (!value.null()) { 636 if (!value.null()) {
635 result.replaceKey(key, replaceForeignIndirectObjects(value, obj_copier, false)); 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 if (!value.null()) { 648 if (!value.null()) {
645 dict.replaceKey(key, replaceForeignIndirectObjects(value, obj_copier, false)); 649 dict.replaceKey(key, replaceForeignIndirectObjects(value, obj_copier, false));
646 } 650 }
647 } 651 }
648 copyStreamData(result, foreign); 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 return result; 659 return result;
660 } 660 }
661 661
qpdf/qpdf.testcov
@@ -126,11 +126,6 @@ QPDF_Stream unknown stream length 0 @@ -126,11 +126,6 @@ QPDF_Stream unknown stream length 0
126 QPDF replaceReserved 0 126 QPDF replaceReserved 0
127 QPDF copyForeign direct 0 127 QPDF copyForeign direct 0
128 QPDF copyForeign not foreign 0 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 QPDFWriter copy use_aes 1 129 QPDFWriter copy use_aes 1
135 QPDFParser indirect without context 0 130 QPDFParser indirect without context 0
136 QPDFObjectHandle trailing data in parse 0 131 QPDFObjectHandle trailing data in parse 0