Commit b0ee84e5b405b0a73cd5c348d17d8f645ddb1043

Authored by m-holger
Committed by GitHub
2 parents 2d6512eb 4c3155b7

Merge pull request #1576 from m-holger/gel

Minor refactorings
libqpdf/NNTree.cc
@@ -872,7 +872,7 @@ QPDFNameTreeObjectHelper::QPDFNameTreeObjectHelper( @@ -872,7 +872,7 @@ QPDFNameTreeObjectHelper::QPDFNameTreeObjectHelper(
872 QPDFNameTreeObjectHelper 872 QPDFNameTreeObjectHelper
873 QPDFNameTreeObjectHelper::newEmpty(QPDF& qpdf, bool auto_repair) 873 QPDFNameTreeObjectHelper::newEmpty(QPDF& qpdf, bool auto_repair)
874 { 874 {
875 - return {qpdf.makeIndirectObject("<< /Names [] >>"_qpdf), qpdf, auto_repair}; 875 + return {qpdf.makeIndirectObject(Dictionary({{"/Names", Array::empty()}})), qpdf, auto_repair};
876 } 876 }
877 877
878 QPDFNameTreeObjectHelper::iterator::iterator(std::shared_ptr<NNTreeIterator> const& i) : 878 QPDFNameTreeObjectHelper::iterator::iterator(std::shared_ptr<NNTreeIterator> const& i) :
@@ -1068,7 +1068,7 @@ QPDFNumberTreeObjectHelper::QPDFNumberTreeObjectHelper( @@ -1068,7 +1068,7 @@ QPDFNumberTreeObjectHelper::QPDFNumberTreeObjectHelper(
1068 QPDFNumberTreeObjectHelper 1068 QPDFNumberTreeObjectHelper
1069 QPDFNumberTreeObjectHelper::newEmpty(QPDF& qpdf, bool auto_repair) 1069 QPDFNumberTreeObjectHelper::newEmpty(QPDF& qpdf, bool auto_repair)
1070 { 1070 {
1071 - return {qpdf.makeIndirectObject("<< /Nums [] >>"_qpdf), qpdf, auto_repair}; 1071 + return {qpdf.makeIndirectObject(Dictionary({{"/Nums", Array::empty()}})), qpdf, auto_repair};
1072 } 1072 }
1073 1073
1074 QPDFNumberTreeObjectHelper::iterator::iterator(std::shared_ptr<NNTreeIterator> const& i) : 1074 QPDFNumberTreeObjectHelper::iterator::iterator(std::shared_ptr<NNTreeIterator> const& i) :
libqpdf/QPDF.cc
@@ -635,21 +635,11 @@ QPDF::getPDFVersion() const @@ -635,21 +635,11 @@ QPDF::getPDFVersion() const
635 int 635 int
636 QPDF::getExtensionLevel() 636 QPDF::getExtensionLevel()
637 { 637 {
638 - int result = 0;  
639 - QPDFObjectHandle obj = getRoot();  
640 - if (obj.hasKey("/Extensions")) {  
641 - obj = obj.getKey("/Extensions");  
642 - if (obj.isDictionary() && obj.hasKey("/ADBE")) {  
643 - obj = obj.getKey("/ADBE");  
644 - if (obj.isDictionary() && obj.hasKey("/ExtensionLevel")) {  
645 - obj = obj.getKey("/ExtensionLevel");  
646 - if (obj.isInteger()) {  
647 - result = obj.getIntValueAsInt();  
648 - }  
649 - }  
650 - } 638 + if (Integer ExtensionLevel = getRoot()["/Extensions"]["/ADBE"]["/ExtensionLevel"]) {
  639 + int result = ExtensionLevel;
  640 + return result;
651 } 641 }
652 - return result; 642 + return 0;
653 } 643 }
654 644
655 QPDFObjectHandle 645 QPDFObjectHandle
@@ -661,17 +651,17 @@ QPDF::getTrailer() @@ -661,17 +651,17 @@ QPDF::getTrailer()
661 QPDFObjectHandle 651 QPDFObjectHandle
662 QPDF::getRoot() 652 QPDF::getRoot()
663 { 653 {
664 - QPDFObjectHandle root = m->trailer.getKey("/Root");  
665 - if (!root.isDictionary()) { 654 + Dictionary Root = m->trailer["/Root"];
  655 + if (!Root) {
666 throw m->c.damagedPDF("", -1, "unable to find /Root dictionary"); 656 throw m->c.damagedPDF("", -1, "unable to find /Root dictionary");
667 - } else if (  
668 - // Check_mode is an interim solution to request #810 pending a more comprehensive review of  
669 - // the approach to more extensive checks and warning levels.  
670 - m->cf.check_mode() && !root.getKey("/Type").isNameAndEquals("/Catalog")) { 657 + }
  658 + // Check_mode is an interim solution to request #810 pending a more comprehensive review of the
  659 + // approach to more extensive checks and warning levels.
  660 + if (m->cf.check_mode() && Name(Root["/Type"]) != "/Catalog") {
671 warn(m->c.damagedPDF("", -1, "catalog /Type entry missing or invalid")); 661 warn(m->c.damagedPDF("", -1, "catalog /Type entry missing or invalid"));
672 - root.replaceKey("/Type", "/Catalog"_qpdf); 662 + Root.replaceKey("/Type", Name("/Catalog"));
673 } 663 }
674 - return root; 664 + return Root.oh();
675 } 665 }
676 666
677 std::map<QPDFObjGen, QPDFXRefEntry> 667 std::map<QPDFObjGen, QPDFXRefEntry>
libqpdf/QPDFJob.cc
@@ -1883,7 +1883,7 @@ QPDFJob::doUnderOverlayForPage( @@ -1883,7 +1883,7 @@ QPDFJob::doUnderOverlayForPage(
1883 fo[from_no.no][uo_idx], name, dest_page.getTrimBox().getArrayAsRectangle(), cm); 1883 fo[from_no.no][uo_idx], name, dest_page.getTrimBox().getArrayAsRectangle(), cm);
1884 dest_page.copyAnnotations(from_page, cm, &dest_afdh, &from_page.qpdf()->doc().acroform()); 1884 dest_page.copyAnnotations(from_page, cm, &dest_afdh, &from_page.qpdf()->doc().acroform());
1885 if (!new_content.empty()) { 1885 if (!new_content.empty()) {
1886 - resources.mergeResources("<< /XObject << >> >>"_qpdf); 1886 + resources.mergeResources(Dictionary({{"/XObject", Dictionary::empty()}}));
1887 auto xobject = resources.getKey("/XObject"); 1887 auto xobject = resources.getKey("/XObject");
1888 if (xobject.isDictionary()) { 1888 if (xobject.isDictionary()) {
1889 xobject.replaceKey(name, fo[from_no.no][uo_idx]); 1889 xobject.replaceKey(name, fo[from_no.no][uo_idx]);
libqpdf/QPDFPageLabelDocumentHelper.cc
@@ -131,19 +131,19 @@ QPDFPageLabelDocumentHelper::pageLabelDict( @@ -131,19 +131,19 @@ QPDFPageLabelDocumentHelper::pageLabelDict(
131 case pl_none: 131 case pl_none:
132 break; 132 break;
133 case pl_digits: 133 case pl_digits:
134 - num.replaceKey("/S", "/D"_qpdf); 134 + num.replaceKey("/S", Name("/D"));
135 break; 135 break;
136 case pl_alpha_lower: 136 case pl_alpha_lower:
137 - num.replaceKey("/S", "/a"_qpdf); 137 + num.replaceKey("/S", Name("/a"));
138 break; 138 break;
139 case pl_alpha_upper: 139 case pl_alpha_upper:
140 - num.replaceKey("/S", "/A"_qpdf); 140 + num.replaceKey("/S", Name("/A"));
141 break; 141 break;
142 case pl_roman_lower: 142 case pl_roman_lower:
143 - num.replaceKey("/S", "/r"_qpdf); 143 + num.replaceKey("/S", Name("/r"));
144 break; 144 break;
145 case pl_roman_upper: 145 case pl_roman_upper:
146 - num.replaceKey("/S", "/R"_qpdf); 146 + num.replaceKey("/S", Name("/R"));
147 break; 147 break;
148 } 148 }
149 if (!prefix.empty()) { 149 if (!prefix.empty()) {
libqpdf/QPDFPageObjectHelper.cc
@@ -406,7 +406,7 @@ QPDFPageObjectHelper::externalizeInlineImages(size_t min_size, bool shallow) @@ -406,7 +406,7 @@ QPDFPageObjectHelper::externalizeInlineImages(size_t min_size, bool shallow)
406 QPDFObjectHandle resources = getAttribute("/Resources", true); 406 QPDFObjectHandle resources = getAttribute("/Resources", true);
407 // Calling mergeResources also ensures that /XObject becomes direct and is not shared with 407 // Calling mergeResources also ensures that /XObject becomes direct and is not shared with
408 // other pages. 408 // other pages.
409 - resources.mergeResources("<< /XObject << >> >>"_qpdf); 409 + resources.mergeResources(Dictionary({{"/XObject", Dictionary::empty()}}));
410 InlineImageTracker iit(oh().getOwningQPDF(), min_size, resources); 410 InlineImageTracker iit(oh().getOwningQPDF(), min_size, resources);
411 Pl_Buffer b("new page content"); 411 Pl_Buffer b("new page content");
412 bool filtered = false; 412 bool filtered = false;
libqpdf/QPDF_pages.cc
@@ -121,7 +121,7 @@ Pages::getAllPagesInternal( @@ -121,7 +121,7 @@ Pages::getAllPagesInternal(
121 // Unconditionally setting the /Type to /Pages could cause problems, but trying to 121 // Unconditionally setting the /Type to /Pages could cause problems, but trying to
122 // accommodate the possibility may be excessive. 122 // accommodate the possibility may be excessive.
123 cur_node.warn("/Type key should be /Pages but is not; overriding"); 123 cur_node.warn("/Type key should be /Pages but is not; overriding");
124 - cur_node.replaceKey("/Type", "/Pages"_qpdf); 124 + cur_node.replaceKey("/Type", Name("/Pages"));
125 } 125 }
126 if (!media_box) { 126 if (!media_box) {
127 media_box = cur_node.getKey("/MediaBox").isRectangle(); 127 media_box = cur_node.getKey("/MediaBox").isRectangle();
@@ -226,7 +226,7 @@ Pages::getAllPagesInternal( @@ -226,7 +226,7 @@ Pages::getAllPagesInternal(
226 } 226 }
227 if (!kid.isDictionaryOfType("/Page")) { 227 if (!kid.isDictionaryOfType("/Page")) {
228 kid.warn("/Type key should be /Page but is not; overriding"); 228 kid.warn("/Type key should be /Page but is not; overriding");
229 - kid.replaceKey("/Type", "/Page"_qpdf); 229 + kid.replaceKey("/Type", Name("/Page"));
230 ++errors; 230 ++errors;
231 } 231 }
232 if (m->reconstructed_xref && errors > 2) { 232 if (m->reconstructed_xref && errors > 2) {
@@ -698,7 +698,7 @@ Pages::flatten_annotations_for_page( @@ -698,7 +698,7 @@ Pages::flatten_annotations_for_page(
698 std::string content = 698 std::string content =
699 aoh.getPageContentForAppearance(name, rotate, required_flags, forbidden_flags); 699 aoh.getPageContentForAppearance(name, rotate, required_flags, forbidden_flags);
700 if (!content.empty()) { 700 if (!content.empty()) {
701 - resources.mergeResources("<< /XObject << >> >>"_qpdf); 701 + resources.mergeResources(Dictionary({{"/XObject", Dictionary({{name, as}})}}));
702 resources.getKey("/XObject").replaceKey(name, as); 702 resources.getKey("/XObject").replaceKey(name, as);
703 ++next_fx; 703 ++next_fx;
704 } 704 }
manual/release-notes.rst
@@ -65,6 +65,10 @@ more detail. @@ -65,6 +65,10 @@ more detail.
65 65
66 - Other changes 66 - Other changes
67 67
  68 + - Calling ``QPDF::getRoot`` on a file with invalid trailer now throws a
  69 + ``damaged_pdf`` error with message "unable to find /Root dictionary"
  70 + rather than an internal error.
  71 +
68 .. _r12-3-0-deprecate: 72 .. _r12-3-0-deprecate:
69 73
70 - The following are believed to be not in use and have been deprecated. 74 - The following are believed to be not in use and have been deprecated.
qpdf/qtest/qpdf/c-oh-errors.out
1 -get root: attempted to dereference an uninitialized QPDFObjectHandle  
2 - code: 1  
3 - file: 1 +get root: closed input source: unable to find /Root dictionary
  2 + code: 5
  3 + file: closed input source
4 pos: 0 4 pos: 0
5 - text: attempted to dereference an uninitialized QPDFObjectHandle 5 + text: unable to find /Root dictionary
6 bad parse: parsed object (offset 1): unknown token while reading object; treating as string 6 bad parse: parsed object (offset 1): unknown token while reading object; treating as string
7 code: 5 7 code: 5
8 file: parsed object 8 file: parsed object
qpdf/qtest/qpdf/test73.out
1 -getRoot: attempted to dereference an uninitialized QPDFObjectHandle 1 +getRoot: closed input source: unable to find /Root dictionary
2 WARNING: closed input source: object 4/0: error reading object: QPDF operation attempted on a QPDF object with no input source. QPDF operations are invalid before processFile (or another process method) or after closeInputSource 2 WARNING: closed input source: object 4/0: error reading object: QPDF operation attempted on a QPDF object with no input source. QPDF operations are invalid before processFile (or another process method) or after closeInputSource
3 test 73 done 3 test 73 done