Commit 06db6493a1776bfda78314697f2f2e4393d9dea4

Authored by m-holger
1 parent decc7d3c

Refactor `QPDFObjectHandle` warnings: replace `warnIfPossible` with centralized …

…`warn`, streamline condition handling.
libqpdf/QPDFAcroFormDocumentHelper.cc
@@ -8,6 +8,7 @@ @@ -8,6 +8,7 @@
8 #include <qpdf/ResourceFinder.hh> 8 #include <qpdf/ResourceFinder.hh>
9 9
10 using namespace qpdf; 10 using namespace qpdf;
  11 +using namespace std::literals;
11 12
12 QPDFAcroFormDocumentHelper::QPDFAcroFormDocumentHelper(QPDF& qpdf) : 13 QPDFAcroFormDocumentHelper::QPDFAcroFormDocumentHelper(QPDF& qpdf) :
13 QPDFDocumentHelper(qpdf), 14 QPDFDocumentHelper(qpdf),
@@ -251,7 +252,7 @@ QPDFAcroFormDocumentHelper::analyze() @@ -251,7 +252,7 @@ QPDFAcroFormDocumentHelper::analyze()
251 } 252 }
252 } else { 253 } else {
253 QTC::TC("qpdf", "QPDFAcroFormDocumentHelper fields not array"); 254 QTC::TC("qpdf", "QPDFAcroFormDocumentHelper fields not array");
254 - acroform.warnIfPossible("/Fields key of /AcroForm dictionary is not an array; ignoring"); 255 + acroform.warn("/Fields key of /AcroForm dictionary is not an array; ignoring");
255 fields = QPDFObjectHandle::newArray(); 256 fields = QPDFObjectHandle::newArray();
256 } 257 }
257 258
@@ -273,9 +274,9 @@ QPDFAcroFormDocumentHelper::analyze() @@ -273,9 +274,9 @@ QPDFAcroFormDocumentHelper::analyze()
273 // case such as a PDF creator adding a self-contained annotation (merged with the 274 // case such as a PDF creator adding a self-contained annotation (merged with the
274 // field dictionary) to the page's /Annots array and forgetting to also put it in 275 // field dictionary) to the page's /Annots array and forgetting to also put it in
275 // /AcroForm. 276 // /AcroForm.
276 - annot.warnIfPossible(  
277 - "this widget annotation is not"  
278 - " reachable from /AcroForm in the document catalog"); 277 + annot.warn(
  278 + "this widget annotation is not reachable from /AcroForm in the document "
  279 + "catalog");
279 m->annotation_to_field[og] = QPDFFormFieldObjectHelper(annot); 280 m->annotation_to_field[og] = QPDFFormFieldObjectHelper(annot);
280 m->field_to_annotations[og].emplace_back(annot); 281 m->field_to_annotations[og].emplace_back(annot);
281 } 282 }
@@ -292,16 +293,16 @@ QPDFAcroFormDocumentHelper::traverseField( @@ -292,16 +293,16 @@ QPDFAcroFormDocumentHelper::traverseField(
292 // could cause stack overflow. 293 // could cause stack overflow.
293 return; 294 return;
294 } 295 }
295 - if (!field.isIndirect()) { 296 + if (!field.indirect()) {
296 QTC::TC("qpdf", "QPDFAcroFormDocumentHelper direct field"); 297 QTC::TC("qpdf", "QPDFAcroFormDocumentHelper direct field");
297 - field.warnIfPossible( 298 + field.warn(
298 "encountered a direct object as a field or annotation while " 299 "encountered a direct object as a field or annotation while "
299 "traversing /AcroForm; ignoring field or annotation"); 300 "traversing /AcroForm; ignoring field or annotation");
300 return; 301 return;
301 } 302 }
302 if (!field.isDictionary()) { 303 if (!field.isDictionary()) {
303 QTC::TC("qpdf", "QPDFAcroFormDocumentHelper non-dictionary field"); 304 QTC::TC("qpdf", "QPDFAcroFormDocumentHelper non-dictionary field");
304 - field.warnIfPossible( 305 + field.warn(
305 "encountered a non-dictionary as a field or annotation while" 306 "encountered a non-dictionary as a field or annotation while"
306 " traversing /AcroForm; ignoring field or annotation"); 307 " traversing /AcroForm; ignoring field or annotation");
307 return; 308 return;
@@ -309,7 +310,7 @@ QPDFAcroFormDocumentHelper::traverseField( @@ -309,7 +310,7 @@ QPDFAcroFormDocumentHelper::traverseField(
309 QPDFObjGen og(field.getObjGen()); 310 QPDFObjGen og(field.getObjGen());
310 if (!visited.add(og)) { 311 if (!visited.add(og)) {
311 QTC::TC("qpdf", "QPDFAcroFormDocumentHelper loop"); 312 QTC::TC("qpdf", "QPDFAcroFormDocumentHelper loop");
312 - field.warnIfPossible("loop detected while traversing /AcroForm"); 313 + field.warn("loop detected while traversing /AcroForm");
313 return; 314 return;
314 } 315 }
315 316
@@ -375,7 +376,7 @@ QPDFAcroFormDocumentHelper::setNeedAppearances(bool val) @@ -375,7 +376,7 @@ QPDFAcroFormDocumentHelper::setNeedAppearances(bool val)
375 { 376 {
376 QPDFObjectHandle acroform = qpdf.getRoot().getKey("/AcroForm"); 377 QPDFObjectHandle acroform = qpdf.getRoot().getKey("/AcroForm");
377 if (!acroform.isDictionary()) { 378 if (!acroform.isDictionary()) {
378 - qpdf.getRoot().warnIfPossible( 379 + qpdf.getRoot().warn(
379 "ignoring call to QPDFAcroFormDocumentHelper::setNeedAppearances" 380 "ignoring call to QPDFAcroFormDocumentHelper::setNeedAppearances"
380 " on a file that lacks an /AcroForm dictionary"); 381 " on a file that lacks an /AcroForm dictionary");
381 return; 382 return;
@@ -592,9 +593,7 @@ QPDFAcroFormDocumentHelper::adjustDefaultAppearances( @@ -592,9 +593,7 @@ QPDFAcroFormDocumentHelper::adjustDefaultAppearances(
592 } catch (std::exception& e) { 593 } catch (std::exception& e) {
593 // No way to reproduce in test suite right now since error conditions are converted to 594 // No way to reproduce in test suite right now since error conditions are converted to
594 // warnings. 595 // warnings.
595 - obj.warnIfPossible(  
596 - std::string("Unable to parse /DA: ") + e.what() +  
597 - "; this form field may not update properly"); 596 + obj.warn("Unable to parse /DA: "s + e.what() + "; this form field may not update properly");
598 return; 597 return;
599 } 598 }
600 599
@@ -677,16 +676,17 @@ QPDFAcroFormDocumentHelper::adjustAppearanceStream( @@ -677,16 +676,17 @@ QPDFAcroFormDocumentHelper::adjustAppearanceStream(
677 try { 676 try {
678 auto nwarnings = qpdf.numWarnings(); 677 auto nwarnings = qpdf.numWarnings();
679 stream.parseAsContents(&rf); 678 stream.parseAsContents(&rf);
680 - if (qpdf.numWarnings() > nwarnings) {  
681 - QTC::TC("qpdf", "QPDFAcroFormDocumentHelper AP parse error");  
682 - } 679 + QTC::TC(
  680 + "qpdf",
  681 + "QPDFAcroFormDocumentHelper AP parse error",
  682 + qpdf.numWarnings() > nwarnings ? 0 : 1);
683 auto rr = new ResourceReplacer(dr_map, rf.getNamesByResourceType()); 683 auto rr = new ResourceReplacer(dr_map, rf.getNamesByResourceType());
684 auto tf = std::shared_ptr<QPDFObjectHandle::TokenFilter>(rr); 684 auto tf = std::shared_ptr<QPDFObjectHandle::TokenFilter>(rr);
685 stream.addTokenFilter(tf); 685 stream.addTokenFilter(tf);
686 } catch (std::exception& e) { 686 } catch (std::exception& e) {
687 // No way to reproduce in test suite right now since error conditions are converted to 687 // No way to reproduce in test suite right now since error conditions are converted to
688 // warnings. 688 // warnings.
689 - stream.warnIfPossible(std::string("Unable to parse appearance stream: ") + e.what()); 689 + stream.warn("Unable to parse appearance stream: "s + e.what());
690 } 690 }
691 } 691 }
692 692
@@ -814,7 +814,7 @@ QPDFAcroFormDocumentHelper::transformAnnotations( @@ -814,7 +814,7 @@ QPDFAcroFormDocumentHelper::transformAnnotations(
814 QPDFObjGen::set added_new_fields; 814 QPDFObjGen::set added_new_fields;
815 for (auto annot: old_annots.aitems()) { 815 for (auto annot: old_annots.aitems()) {
816 if (annot.isStream()) { 816 if (annot.isStream()) {
817 - annot.warnIfPossible("ignoring annotation that's a stream"); 817 + annot.warn("ignoring annotation that's a stream");
818 continue; 818 continue;
819 } 819 }
820 820
@@ -847,10 +847,10 @@ QPDFAcroFormDocumentHelper::transformAnnotations( @@ -847,10 +847,10 @@ QPDFAcroFormDocumentHelper::transformAnnotations(
847 bool have_field = false; 847 bool have_field = false;
848 bool have_parent = false; 848 bool have_parent = false;
849 if (ffield_oh.isStream()) { 849 if (ffield_oh.isStream()) {
850 - ffield_oh.warnIfPossible("ignoring form field that's a stream"); 850 + ffield.warn("ignoring form field that's a stream");
851 } else if ((!ffield_oh.isNull()) && (!ffield_oh.isIndirect())) { 851 } else if ((!ffield_oh.isNull()) && (!ffield_oh.isIndirect())) {
852 - ffield_oh.warnIfPossible("ignoring form field not indirect");  
853 - } else if (!ffield_oh.isNull()) { 852 + ffield.warn("ignoring form field not indirect");
  853 + } else if (!ffield.null()) {
854 // A field and its associated annotation can be the same object. This matters because we 854 // A field and its associated annotation can be the same object. This matters because we
855 // don't want to clone the annotation and field separately in this case. 855 // don't want to clone the annotation and field separately in this case.
856 have_field = true; 856 have_field = true;
@@ -888,7 +888,7 @@ QPDFAcroFormDocumentHelper::transformAnnotations( @@ -888,7 +888,7 @@ QPDFAcroFormDocumentHelper::transformAnnotations(
888 if (orig_to_copy.contains(parent_og)) { 888 if (orig_to_copy.contains(parent_og)) {
889 obj.replaceKey("/Parent", orig_to_copy[parent_og]); 889 obj.replaceKey("/Parent", orig_to_copy[parent_og]);
890 } else { 890 } else {
891 - parent.warnIfPossible( 891 + parent.warn(
892 "while traversing field " + obj.getObjGen().unparse(',') + 892 "while traversing field " + obj.getObjGen().unparse(',') +
893 ", found parent (" + parent_og.unparse(',') + 893 ", found parent (" + parent_og.unparse(',') +
894 ") that had not been seen, indicating likely invalid field " 894 ") that had not been seen, indicating likely invalid field "
libqpdf/QPDFEFStreamObjectHelper.cc
@@ -138,7 +138,7 @@ QPDFEFStreamObjectHelper::newFromStream(QPDFObjectHandle stream) @@ -138,7 +138,7 @@ QPDFEFStreamObjectHelper::newFromStream(QPDFObjectHandle stream)
138 Pl_MD5 md5("EF md5", &discard); 138 Pl_MD5 md5("EF md5", &discard);
139 Pl_Count count("EF size", &md5); 139 Pl_Count count("EF size", &md5);
140 if (!stream.pipeStreamData(&count, nullptr, 0, qpdf_dl_all)) { 140 if (!stream.pipeStreamData(&count, nullptr, 0, qpdf_dl_all)) {
141 - stream.warnIfPossible("unable to get stream data for new embedded file stream"); 141 + stream.warn("unable to get stream data for new embedded file stream");
142 } else { 142 } else {
143 result.setParam("/Size", QPDFObjectHandle::newInteger(count.getCount())); 143 result.setParam("/Size", QPDFObjectHandle::newInteger(count.getCount()));
144 result.setParam( 144 result.setParam(
libqpdf/QPDFFileSpecObjectHelper.cc
@@ -4,32 +4,33 @@ @@ -4,32 +4,33 @@
4 #include <qpdf/QTC.hh> 4 #include <qpdf/QTC.hh>
5 #include <qpdf/QUtil.hh> 5 #include <qpdf/QUtil.hh>
6 6
  7 +#include <array>
7 #include <string> 8 #include <string>
8 -#include <vector> 9 +
  10 +using namespace std::literals;
9 11
10 QPDFFileSpecObjectHelper::QPDFFileSpecObjectHelper(QPDFObjectHandle oh) : 12 QPDFFileSpecObjectHelper::QPDFFileSpecObjectHelper(QPDFObjectHandle oh) :
11 QPDFObjectHelper(oh) 13 QPDFObjectHelper(oh)
12 { 14 {
13 if (!oh.isDictionary()) { 15 if (!oh.isDictionary()) {
14 - oh.warnIfPossible("Embedded file object is not a dictionary"); 16 + warn("Embedded file object is not a dictionary");
15 return; 17 return;
16 } 18 }
17 if (!oh.isDictionaryOfType("/Filespec")) { 19 if (!oh.isDictionaryOfType("/Filespec")) {
18 - oh.warnIfPossible("Embedded file object's type is not /Filespec"); 20 + warn("Embedded file object's type is not /Filespec");
19 } 21 }
20 } 22 }
21 23
22 -static std::vector<std::string> name_keys = {"/UF", "/F", "/Unix", "/DOS", "/Mac"}; 24 +static const std::array<std::string, 5> name_keys = {"/UF"s, "/F"s, "/Unix"s, "/DOS"s, "/Mac"s};
23 25
24 std::string 26 std::string
25 QPDFFileSpecObjectHelper::getDescription() 27 QPDFFileSpecObjectHelper::getDescription()
26 { 28 {
27 - std::string result;  
28 auto desc = oh().getKey("/Desc"); 29 auto desc = oh().getKey("/Desc");
29 if (desc.isString()) { 30 if (desc.isString()) {
30 - result = desc.getUTF8Value(); 31 + return desc.getUTF8Value();
31 } 32 }
32 - return result; 33 + return {};
33 } 34 }
34 35
35 std::string 36 std::string
libqpdf/QPDFFormFieldObjectHelper.cc
@@ -317,18 +317,17 @@ QPDFFormFieldObjectHelper::setV(QPDFObjectHandle value, bool need_appearances) @@ -317,18 +317,17 @@ QPDFFormFieldObjectHelper::setV(QPDFObjectHandle value, bool need_appearances)
317 setCheckBoxValue((name != "/Off")); 317 setCheckBoxValue((name != "/Off"));
318 } 318 }
319 if (!okay) { 319 if (!okay) {
320 - oh().warnIfPossible(  
321 - "ignoring attempt to set a checkbox field to a value whose type is not name"); 320 + warn("ignoring attempt to set a checkbox field to a value whose type is not name");
322 } 321 }
323 } else if (isRadioButton()) { 322 } else if (isRadioButton()) {
324 if (value.isName()) { 323 if (value.isName()) {
325 setRadioButtonValue(value); 324 setRadioButtonValue(value);
326 } else { 325 } else {
327 - oh().warnIfPossible( 326 + warn(
328 "ignoring attempt to set a radio button field to an object that is not a name"); 327 "ignoring attempt to set a radio button field to an object that is not a name");
329 } 328 }
330 } else if (isPushbutton()) { 329 } else if (isPushbutton()) {
331 - oh().warnIfPossible("ignoring attempt set the value of a pushbutton field"); 330 + warn("ignoring attempt set the value of a pushbutton field");
332 } 331 }
333 return; 332 return;
334 } 333 }
@@ -375,7 +374,7 @@ QPDFFormFieldObjectHelper::setRadioButtonValue(QPDFObjectHandle name) @@ -375,7 +374,7 @@ QPDFFormFieldObjectHelper::setRadioButtonValue(QPDFObjectHandle name)
375 374
376 QPDFObjectHandle kids = oh().getKey("/Kids"); 375 QPDFObjectHandle kids = oh().getKey("/Kids");
377 if (!(isRadioButton() && parent.isNull() && kids.isArray())) { 376 if (!(isRadioButton() && parent.isNull() && kids.isArray())) {
378 - oh().warnIfPossible("don't know how to set the value of this field as a radio button"); 377 + warn("don't know how to set the value of this field as a radio button");
379 return; 378 return;
380 } 379 }
381 setFieldAttribute("/V", name); 380 setFieldAttribute("/V", name);
@@ -397,7 +396,7 @@ QPDFFormFieldObjectHelper::setRadioButtonValue(QPDFObjectHandle name) @@ -397,7 +396,7 @@ QPDFFormFieldObjectHelper::setRadioButtonValue(QPDFObjectHandle name)
397 } 396 }
398 if (!annot) { 397 if (!annot) {
399 QTC::TC("qpdf", "QPDFObjectHandle broken radio button"); 398 QTC::TC("qpdf", "QPDFObjectHandle broken radio button");
400 - oh().warnIfPossible("unable to set the value of this radio button"); 399 + warn("unable to set the value of this radio button");
401 continue; 400 continue;
402 } 401 }
403 if (AP.isDictionary() && AP.getKey("/N").isDictionary() && 402 if (AP.isDictionary() && AP.getKey("/N").isDictionary() &&
@@ -453,7 +452,7 @@ QPDFFormFieldObjectHelper::setCheckBoxValue(bool value) @@ -453,7 +452,7 @@ QPDFFormFieldObjectHelper::setCheckBoxValue(bool value)
453 setFieldAttribute("/V", name); 452 setFieldAttribute("/V", name);
454 if (!annot) { 453 if (!annot) {
455 QTC::TC("qpdf", "QPDFObjectHandle broken checkbox"); 454 QTC::TC("qpdf", "QPDFObjectHandle broken checkbox");
456 - oh().warnIfPossible("unable to set the value of this checkbox"); 455 + warn("unable to set the value of this checkbox");
457 return; 456 return;
458 } 457 }
459 QTC::TC("qpdf", "QPDFFormFieldObjectHelper set checkbox AS"); 458 QTC::TC("qpdf", "QPDFFormFieldObjectHelper set checkbox AS");
@@ -770,18 +769,17 @@ QPDFFormFieldObjectHelper::generateTextAppearance(QPDFAnnotationObjectHelper&amp; ao @@ -770,18 +769,17 @@ QPDFFormFieldObjectHelper::generateTextAppearance(QPDFAnnotationObjectHelper&amp; ao
770 AP.replaceKey("/N", AS); 769 AP.replaceKey("/N", AS);
771 } 770 }
772 if (!AS.isStream()) { 771 if (!AS.isStream()) {
773 - aoh.getObjectHandle().warnIfPossible("unable to get normal appearance stream for update"); 772 + aoh.warn("unable to get normal appearance stream for update");
774 return; 773 return;
775 } 774 }
776 775
777 if (AS.getObj().use_count() > 4) { 776 if (AS.getObj().use_count() > 4) {
778 - aoh.getObjectHandle().warnIfPossible(  
779 - "unable to generate text appearance from shared appearance stream for update"); 777 + aoh.warn("unable to generate text appearance from shared appearance stream for update");
780 return; 778 return;
781 } 779 }
782 QPDFObjectHandle bbox_obj = AS.getDict().getKey("/BBox"); 780 QPDFObjectHandle bbox_obj = AS.getDict().getKey("/BBox");
783 if (!bbox_obj.isRectangle()) { 781 if (!bbox_obj.isRectangle()) {
784 - aoh.getObjectHandle().warnIfPossible("unable to get appearance stream bounding box"); 782 + aoh.warn("unable to get appearance stream bounding box");
785 return; 783 return;
786 } 784 }
787 QPDFObjectHandle::Rectangle bbox = bbox_obj.getArrayAsRectangle(); 785 QPDFObjectHandle::Rectangle bbox = bbox_obj.getArrayAsRectangle();
libqpdf/QPDFObjectHandle.cc
@@ -835,20 +835,16 @@ QPDFObjectHandle::getValueAsInt(long long&amp; value) const @@ -835,20 +835,16 @@ QPDFObjectHandle::getValueAsInt(long long&amp; value) const
835 int 835 int
836 QPDFObjectHandle::getIntValueAsInt() const 836 QPDFObjectHandle::getIntValueAsInt() const
837 { 837 {
838 - int result = 0;  
839 long long v = getIntValue(); 838 long long v = getIntValue();
840 if (v < INT_MIN) { 839 if (v < INT_MIN) {
841 - QTC::TC("qpdf", "QPDFObjectHandle int returning INT_MIN");  
842 - warnIfPossible("requested value of integer is too small; returning INT_MIN");  
843 - result = INT_MIN;  
844 - } else if (v > INT_MAX) {  
845 - QTC::TC("qpdf", "QPDFObjectHandle int returning INT_MAX");  
846 - warnIfPossible("requested value of integer is too big; returning INT_MAX");  
847 - result = INT_MAX;  
848 - } else {  
849 - result = static_cast<int>(v); 840 + warn("requested value of integer is too small; returning INT_MIN");
  841 + return INT_MIN;
850 } 842 }
851 - return result; 843 + if (v > INT_MAX) {
  844 + warn("requested value of integer is too big; returning INT_MAX");
  845 + return INT_MAX;
  846 + }
  847 + return static_cast<int>(v);
852 } 848 }
853 849
854 bool 850 bool
@@ -866,8 +862,7 @@ QPDFObjectHandle::getUIntValue() const @@ -866,8 +862,7 @@ QPDFObjectHandle::getUIntValue() const
866 { 862 {
867 long long v = getIntValue(); 863 long long v = getIntValue();
868 if (v < 0) { 864 if (v < 0) {
869 - QTC::TC("qpdf", "QPDFObjectHandle uint returning 0");  
870 - warnIfPossible("unsigned value request for negative number; returning 0"); 865 + warn("unsigned value request for negative number; returning 0");
871 return 0; 866 return 0;
872 } else { 867 } else {
873 return static_cast<unsigned long long>(v); 868 return static_cast<unsigned long long>(v);
@@ -889,16 +884,14 @@ QPDFObjectHandle::getUIntValueAsUInt() const @@ -889,16 +884,14 @@ QPDFObjectHandle::getUIntValueAsUInt() const
889 { 884 {
890 long long v = getIntValue(); 885 long long v = getIntValue();
891 if (v < 0) { 886 if (v < 0) {
892 - QTC::TC("qpdf", "QPDFObjectHandle uint uint returning 0");  
893 - warnIfPossible("unsigned integer value request for negative number; returning 0"); 887 + warn("unsigned integer value request for negative number; returning 0");
894 return 0; 888 return 0;
895 - } else if (v > UINT_MAX) {  
896 - QTC::TC("qpdf", "QPDFObjectHandle uint returning UINT_MAX");  
897 - warnIfPossible("requested value of unsigned integer is too big; returning UINT_MAX"); 889 + }
  890 + if (v > UINT_MAX) {
  891 + warn("requested value of unsigned integer is too big; returning UINT_MAX");
898 return UINT_MAX; 892 return UINT_MAX;
899 - } else {  
900 - return static_cast<unsigned int>(v);  
901 } 893 }
  894 + return static_cast<unsigned int>(v);
902 } 895 }
903 896
904 bool 897 bool
libqpdf/QPDFPageDocumentHelper.cc
@@ -59,7 +59,7 @@ QPDFPageDocumentHelper::flattenAnnotations(int required_flags, int forbidden_fla @@ -59,7 +59,7 @@ QPDFPageDocumentHelper::flattenAnnotations(int required_flags, int forbidden_fla
59 if (afdh.getNeedAppearances()) { 59 if (afdh.getNeedAppearances()) {
60 qpdf.getRoot() 60 qpdf.getRoot()
61 .getKey("/AcroForm") 61 .getKey("/AcroForm")
62 - .warnIfPossible( 62 + .warn(
63 "document does not have updated appearance streams, so form fields " 63 "document does not have updated appearance streams, so form fields "
64 "will not be flattened"); 64 "will not be flattened");
65 } 65 }
libqpdf/QPDFPageObjectHelper.cc
@@ -12,6 +12,8 @@ @@ -12,6 +12,8 @@
12 #include <qpdf/QUtil.hh> 12 #include <qpdf/QUtil.hh>
13 #include <qpdf/ResourceFinder.hh> 13 #include <qpdf/ResourceFinder.hh>
14 14
  15 +using namespace std::literals;
  16 +
15 namespace 17 namespace
16 { 18 {
17 class ContentProvider: public QPDFObjectHandle::StreamDataProvider 19 class ContentProvider: public QPDFObjectHandle::StreamDataProvider
@@ -118,7 +120,7 @@ InlineImageTracker::convertIIDict(QPDFObjectHandle odict) @@ -118,7 +120,7 @@ InlineImageTracker::convertIIDict(QPDFObjectHandle odict)
118 QTC::TC("qpdf", "QPDFPageObjectHelper colorspace lookup"); 120 QTC::TC("qpdf", "QPDFPageObjectHelper colorspace lookup");
119 value = colorspace.getKey(name); 121 value = colorspace.getKey(name);
120 } else { 122 } else {
121 - resources.warnIfPossible("unable to resolve colorspace " + name); 123 + resources.warn("unable to resolve colorspace " + name);
122 } 124 }
123 name.clear(); 125 name.clear();
124 } 126 }
@@ -414,8 +416,8 @@ QPDFPageObjectHelper::externalizeInlineImages(size_t min_size, bool shallow) @@ -414,8 +416,8 @@ QPDFPageObjectHelper::externalizeInlineImages(size_t min_size, bool shallow)
414 filterContents(&iit, &b); 416 filterContents(&iit, &b);
415 filtered = true; 417 filtered = true;
416 } catch (std::exception& e) { 418 } catch (std::exception& e) {
417 - oh().warnIfPossible(  
418 - std::string("Unable to filter content stream: ") + e.what() + 419 + warn(
  420 + "Unable to filter content stream: "s + e.what() +
419 "; not attempting to externalize inline images from this stream"); 421 "; not attempting to externalize inline images from this stream");
420 } 422 }
421 if (filtered && iit.any_images) { 423 if (filtered && iit.any_images) {
@@ -555,15 +557,15 @@ QPDFPageObjectHelper::removeUnreferencedResourcesHelper( @@ -555,15 +557,15 @@ QPDFPageObjectHelper::removeUnreferencedResourcesHelper(
555 ph.parseContents(&rf); 557 ph.parseContents(&rf);
556 size_t after_nw = (q ? q->numWarnings() : 0); 558 size_t after_nw = (q ? q->numWarnings() : 0);
557 if (after_nw > before_nw) { 559 if (after_nw > before_nw) {
558 - ph.oh().warnIfPossible( 560 + ph.warn(
559 "Bad token found while scanning content stream; " 561 "Bad token found while scanning content stream; "
560 "not attempting to remove unreferenced objects from this object"); 562 "not attempting to remove unreferenced objects from this object");
561 return false; 563 return false;
562 } 564 }
563 } catch (std::exception& e) { 565 } catch (std::exception& e) {
564 QTC::TC("qpdf", "QPDFPageObjectHelper bad token finding names"); 566 QTC::TC("qpdf", "QPDFPageObjectHelper bad token finding names");
565 - ph.oh().warnIfPossible(  
566 - std::string("Unable to parse content stream: ") + e.what() + 567 + ph.warn(
  568 + "Unable to parse content stream: "s + e.what() +
567 "; not attempting to remove unreferenced objects from this object"); 569 "; not attempting to remove unreferenced objects from this object");
568 return false; 570 return false;
569 } 571 }
@@ -719,8 +721,7 @@ QPDFPageObjectHelper::getFormXObjectForPage(bool handle_transformations) @@ -719,8 +721,7 @@ QPDFPageObjectHelper::getFormXObjectForPage(bool handle_transformations)
719 newdict.replaceKey("/Group", getAttribute("/Group", false).shallowCopy()); 721 newdict.replaceKey("/Group", getAttribute("/Group", false).shallowCopy());
720 QPDFObjectHandle bbox = getTrimBox(false).shallowCopy(); 722 QPDFObjectHandle bbox = getTrimBox(false).shallowCopy();
721 if (!bbox.isRectangle()) { 723 if (!bbox.isRectangle()) {
722 - oh().warnIfPossible(  
723 - "bounding box is invalid; form XObject created from page will not work"); 724 + warn("bounding box is invalid; form XObject created from page will not work");
724 } 725 }
725 newdict.replaceKey("/BBox", bbox); 726 newdict.replaceKey("/BBox", bbox);
726 auto provider = 727 auto provider =
libqpdf/QPDFWriter.cc
@@ -1396,8 +1396,8 @@ QPDFWriter::willFilterStream( @@ -1396,8 +1396,8 @@ QPDFWriter::willFilterStream(
1396 } 1396 }
1397 } catch (std::runtime_error& e) { 1397 } catch (std::runtime_error& e) {
1398 if (filter && first_attempt) { 1398 if (filter && first_attempt) {
1399 - stream.warnIfPossible("error while getting stream data: "s + e.what());  
1400 - stream.warnIfPossible("qpdf will attempt to write the damaged stream unchanged"); 1399 + stream.warn("error while getting stream data: "s + e.what());
  1400 + stream.warn("qpdf will attempt to write the damaged stream unchanged");
1401 filter = false; 1401 filter = false;
1402 stream.setFilterOnWrite(false); 1402 stream.setFilterOnWrite(false);
1403 continue; 1403 continue;
@@ -1742,7 +1742,7 @@ QPDFWriter::writeObjectStream(QPDFObjectHandle object) @@ -1742,7 +1742,7 @@ QPDFWriter::writeObjectStream(QPDFObjectHandle object)
1742 if (obj_to_write.isStream()) { 1742 if (obj_to_write.isStream()) {
1743 // This condition occurred in a fuzz input. Ideally we should block it at parse 1743 // This condition occurred in a fuzz input. Ideally we should block it at parse
1744 // time, but it's not clear to me how to construct a case for this. 1744 // time, but it's not clear to me how to construct a case for this.
1745 - obj_to_write.warnIfPossible("stream found inside object stream; treating as null"); 1745 + obj_to_write.warn("stream found inside object stream; treating as null");
1746 obj_to_write = QPDFObjectHandle::newNull(); 1746 obj_to_write = QPDFObjectHandle::newNull();
1747 } 1747 }
1748 writeObject(obj_to_write, count); 1748 writeObject(obj_to_write, count);
libqpdf/QPDF_pages.cc
@@ -57,7 +57,7 @@ QPDF::getAllPages() @@ -57,7 +57,7 @@ QPDF::getAllPages()
57 // Files have been found in the wild where /Pages in the catalog points to the first 57 // Files have been found in the wild where /Pages in the catalog points to the first
58 // page. Try to work around this and similar cases with this heuristic. 58 // page. Try to work around this and similar cases with this heuristic.
59 if (!warned) { 59 if (!warned) {
60 - root.warnIfPossible( 60 + root.warn(
61 "document page tree root (root -> /Pages) doesn't point" 61 "document page tree root (root -> /Pages) doesn't point"
62 " to the root of the page tree; attempting to correct"); 62 " to the root of the page tree; attempting to correct");
63 warned = true; 63 warned = true;
@@ -109,7 +109,7 @@ QPDF::getAllPagesInternal( @@ -109,7 +109,7 @@ QPDF::getAllPagesInternal(
109 // During fuzzing files were encountered where the root object appeared in the pages tree. 109 // During fuzzing files were encountered where the root object appeared in the pages tree.
110 // Unconditionally setting the /Type to /Pages could cause problems, but trying to 110 // Unconditionally setting the /Type to /Pages could cause problems, but trying to
111 // accommodate the possibility may be excessive. 111 // accommodate the possibility may be excessive.
112 - cur_node.warnIfPossible("/Type key should be /Pages but is not; overriding"); 112 + cur_node.warn("/Type key should be /Pages but is not; overriding");
113 cur_node.replaceKey("/Type", "/Pages"_qpdf); 113 cur_node.replaceKey("/Type", "/Pages"_qpdf);
114 } 114 }
115 if (!media_box) { 115 if (!media_box) {
@@ -134,13 +134,13 @@ QPDF::getAllPagesInternal( @@ -134,13 +134,13 @@ QPDF::getAllPagesInternal(
134 int errors = 0; 134 int errors = 0;
135 135
136 if (!kid.isDictionary()) { 136 if (!kid.isDictionary()) {
137 - kid.warnIfPossible("Pages tree includes non-dictionary object; ignoring"); 137 + kid.warn("Pages tree includes non-dictionary object; ignoring");
138 m->invalid_page_found = true; 138 m->invalid_page_found = true;
139 continue; 139 continue;
140 } 140 }
141 if (!kid.isIndirect()) { 141 if (!kid.isIndirect()) {
142 QTC::TC("qpdf", "QPDF handle direct page object"); 142 QTC::TC("qpdf", "QPDF handle direct page object");
143 - cur_node.warnIfPossible( 143 + cur_node.warn(
144 "kid " + std::to_string(i) + " (from 0) is direct; converting to indirect"); 144 "kid " + std::to_string(i) + " (from 0) is direct; converting to indirect");
145 kid = makeIndirectObject(kid); 145 kid = makeIndirectObject(kid);
146 ++errors; 146 ++errors;
@@ -150,7 +150,7 @@ QPDF::getAllPagesInternal( @@ -150,7 +150,7 @@ QPDF::getAllPagesInternal(
150 } else { 150 } else {
151 if (!media_box && !kid.getKey("/MediaBox").isRectangle()) { 151 if (!media_box && !kid.getKey("/MediaBox").isRectangle()) {
152 QTC::TC("qpdf", "QPDF missing mediabox"); 152 QTC::TC("qpdf", "QPDF missing mediabox");
153 - kid.warnIfPossible( 153 + kid.warn(
154 "kid " + std::to_string(i) + 154 "kid " + std::to_string(i) +
155 " (from 0) MediaBox is undefined; setting to letter / ANSI A"); 155 " (from 0) MediaBox is undefined; setting to letter / ANSI A");
156 kid.replaceKey( 156 kid.replaceKey(
@@ -167,7 +167,7 @@ QPDF::getAllPagesInternal( @@ -167,7 +167,7 @@ QPDF::getAllPagesInternal(
167 // QPDFPageObjectHelper. 167 // QPDFPageObjectHelper.
168 QTC::TC("qpdf", "QPDF resolve duplicated page object"); 168 QTC::TC("qpdf", "QPDF resolve duplicated page object");
169 if (!m->reconstructed_xref) { 169 if (!m->reconstructed_xref) {
170 - cur_node.warnIfPossible( 170 + cur_node.warn(
171 "kid " + std::to_string(i) + 171 "kid " + std::to_string(i) +
172 " (from 0) appears more than once in the pages tree;" 172 " (from 0) appears more than once in the pages tree;"
173 " creating a new page object as a copy"); 173 " creating a new page object as a copy");
@@ -176,7 +176,7 @@ QPDF::getAllPagesInternal( @@ -176,7 +176,7 @@ QPDF::getAllPagesInternal(
176 kid = makeIndirectObject(QPDFObjectHandle(kid).shallowCopy()); 176 kid = makeIndirectObject(QPDFObjectHandle(kid).shallowCopy());
177 seen.add(kid); 177 seen.add(kid);
178 } else { 178 } else {
179 - cur_node.warnIfPossible( 179 + cur_node.warn(
180 "kid " + std::to_string(i) + 180 "kid " + std::to_string(i) +
181 " (from 0) appears more than once in the pages tree; ignoring duplicate"); 181 " (from 0) appears more than once in the pages tree; ignoring duplicate");
182 m->invalid_page_found = true; 182 m->invalid_page_found = true;
@@ -189,12 +189,12 @@ QPDF::getAllPagesInternal( @@ -189,12 +189,12 @@ QPDF::getAllPagesInternal(
189 } 189 }
190 } 190 }
191 if (!kid.isDictionaryOfType("/Page")) { 191 if (!kid.isDictionaryOfType("/Page")) {
192 - kid.warnIfPossible("/Type key should be /Page but is not; overriding"); 192 + kid.warn("/Type key should be /Page but is not; overriding");
193 kid.replaceKey("/Type", "/Page"_qpdf); 193 kid.replaceKey("/Type", "/Page"_qpdf);
194 ++errors; 194 ++errors;
195 } 195 }
196 if (m->reconstructed_xref && errors > 2) { 196 if (m->reconstructed_xref && errors > 2) {
197 - cur_node.warnIfPossible( 197 + cur_node.warn(
198 "kid " + std::to_string(i) + " (from 0) has too many errors; ignoring page"); 198 "kid " + std::to_string(i) + " (from 0) has too many errors; ignoring page");
199 m->invalid_page_found = true; 199 m->invalid_page_found = true;
200 kid = QPDFObjectHandle::newNull(); 200 kid = QPDFObjectHandle::newNull();
qpdf/qpdf.testcov
@@ -424,11 +424,6 @@ QPDFPageObjectHelper keep inline image 0 @@ -424,11 +424,6 @@ QPDFPageObjectHelper keep inline image 0
424 QPDFJob image optimize colorspace 0 424 QPDFJob image optimize colorspace 0
425 QPDFJob image optimize bits per component 0 425 QPDFJob image optimize bits per component 0
426 QPDFWriter remove empty DecodeParms 0 426 QPDFWriter remove empty DecodeParms 0
427 -QPDFObjectHandle uint returning 0 0  
428 -QPDFObjectHandle int returning INT_MIN 0  
429 -QPDFObjectHandle int returning INT_MAX 0  
430 -QPDFObjectHandle uint returning UINT_MAX 0  
431 -QPDFObjectHandle uint uint returning 0 0  
432 QPDF xref skipped space 0 427 QPDF xref skipped space 0
433 QPDF eof skipping spaces before xref 1 428 QPDF eof skipping spaces before xref 1
434 QPDF_encryption user matches owner V < 5 0 429 QPDF_encryption user matches owner V < 5 0
@@ -592,7 +587,7 @@ QPDFAcroFormDocumentHelper replaced DA token 0 @@ -592,7 +587,7 @@ QPDFAcroFormDocumentHelper replaced DA token 0
592 QPDFAcroFormDocumentHelper ap conflict 0 587 QPDFAcroFormDocumentHelper ap conflict 0
593 QPDFAcroFormDocumentHelper ap rename 0 588 QPDFAcroFormDocumentHelper ap rename 0
594 QPDFAcroFormDocumentHelper /DA parse error 0 589 QPDFAcroFormDocumentHelper /DA parse error 0
595 -QPDFAcroFormDocumentHelper AP parse error 0 590 +QPDFAcroFormDocumentHelper AP parse error 1
596 QPDFJob copy fields not this file 0 591 QPDFJob copy fields not this file 0
597 QPDFJob copy fields non-first from orig 0 592 QPDFJob copy fields non-first from orig 0
598 QPDF resolve duplicated page in insert 0 593 QPDF resolve duplicated page in insert 0