Commit 04f45cf652f2ee30a677933817aef8971a1f533d

Authored by Jay Berkenbilt
1 parent 0b45dfd3

Treat all linearization errors as warnings

This also reverts the addition of a new checkLinearization that
distinguishes errors from warnings. There's no practical distinction
between what was considered an error and what was considered a
warning.
include/qpdf/QPDF.hh
@@ -477,15 +477,13 @@ class QPDF @@ -477,15 +477,13 @@ class QPDF
477 QPDF_DLL 477 QPDF_DLL
478 bool isLinearized(); 478 bool isLinearized();
479 479
480 - // Performs various sanity checks on a linearized file. Return  
481 - // true if no errors or warnings. Otherwise, return false and 480 + // Performs various sanity checks on a linearized file. Return
  481 + // true if no errors or warnings. Otherwise, return false and
482 // output errors and warnings to std::cout or the output stream 482 // output errors and warnings to std::cout or the output stream
483 - // specified in a call to setOutputStreams. 483 + // specified in a call to setOutputStreams. It is recommended for
  484 + // linearization errors to be treated as warnings.
484 QPDF_DLL 485 QPDF_DLL
485 bool checkLinearization(); 486 bool checkLinearization();
486 - // Separately indicate whether there were errors or warnings.  
487 - QPDF_DLL  
488 - void checkLinearization(bool& errors, bool& warnings);  
489 487
490 // Calls checkLinearization() and, if possible, prints normalized 488 // Calls checkLinearization() and, if possible, prints normalized
491 // contents of some of the hints tables to std::cout or the output 489 // contents of some of the hints tables to std::cout or the output
@@ -1229,7 +1227,7 @@ class QPDF @@ -1229,7 +1227,7 @@ class QPDF
1229 // methods to support linearization checking -- implemented in 1227 // methods to support linearization checking -- implemented in
1230 // QPDF_linearization.cc 1228 // QPDF_linearization.cc
1231 void readLinearizationData(); 1229 void readLinearizationData();
1232 - void checkLinearizationInternal(bool& errors, bool& warnings); 1230 + bool checkLinearizationInternal();
1233 void dumpLinearizationDataInternal(); 1231 void dumpLinearizationDataInternal();
1234 QPDFObjectHandle readHintStream( 1232 QPDFObjectHandle readHintStream(
1235 Pipeline&, qpdf_offset_t offset, size_t length); 1233 Pipeline&, qpdf_offset_t offset, size_t length);
libqpdf/QPDF_linearization.cc
@@ -65,25 +65,17 @@ load_vector_vector(BitStream& bit_stream, @@ -65,25 +65,17 @@ load_vector_vector(BitStream& bit_stream,
65 bool 65 bool
66 QPDF::checkLinearization() 66 QPDF::checkLinearization()
67 { 67 {
68 - bool errors = false;  
69 - bool warnings = false;  
70 - checkLinearization(errors, warnings);  
71 - return (! (errors || warnings));  
72 -}  
73 -  
74 -void  
75 -QPDF::checkLinearization(bool& errors, bool& warnings)  
76 -{ 68 + bool result = false;
77 try 69 try
78 { 70 {
79 readLinearizationData(); 71 readLinearizationData();
80 - checkLinearizationInternal(errors, warnings); 72 + result = checkLinearizationInternal();
81 } 73 }
82 catch (QPDFExc& e) 74 catch (QPDFExc& e)
83 { 75 {
84 *this->m->out_stream << e.what() << std::endl; 76 *this->m->out_stream << e.what() << std::endl;
85 - errors = true;  
86 } 77 }
  78 + return result;
87 } 79 }
88 80
89 bool 81 bool
@@ -507,8 +499,8 @@ QPDF::readHGeneric(BitStream h, HGeneric&amp; t) @@ -507,8 +499,8 @@ QPDF::readHGeneric(BitStream h, HGeneric&amp; t)
507 t.group_length = h.getBitsInt(32); // 4 499 t.group_length = h.getBitsInt(32); // 4
508 } 500 }
509 501
510 -void  
511 -QPDF::checkLinearizationInternal(bool& any_errors, bool& any_warnings) 502 +bool
  503 +QPDF::checkLinearizationInternal()
512 { 504 {
513 // All comments referring to the PDF spec refer to the spec for 505 // All comments referring to the PDF spec refer to the spec for
514 // version 1.4. 506 // version 1.4.
@@ -656,26 +648,34 @@ QPDF::checkLinearizationInternal(bool&amp; any_errors, bool&amp; any_warnings) @@ -656,26 +648,34 @@ QPDF::checkLinearizationInternal(bool&amp; any_errors, bool&amp; any_warnings)
656 648
657 // Report errors 649 // Report errors
658 650
659 - any_errors = (! errors.empty());  
660 - any_warnings = (! warnings.empty()); 651 + bool result = true;
661 652
662 - if (any_errors) 653 + // Treat all linearization errors as warnings. Many of them occur
  654 + // in otherwise working files, so it's really misleading to treat
  655 + // them as errors. We'll hang onto the distinction in the code for
  656 + // now in case we ever have a chance to clean up the linearization
  657 + // code.
  658 + if (! errors.empty())
663 { 659 {
  660 + result = false;
664 for (std::list<std::string>::iterator iter = errors.begin(); 661 for (std::list<std::string>::iterator iter = errors.begin();
665 iter != errors.end(); ++iter) 662 iter != errors.end(); ++iter)
666 { 663 {
667 - *this->m->out_stream << "ERROR: " << (*iter) << std::endl; 664 + *this->m->out_stream << "WARNING: " << (*iter) << std::endl;
668 } 665 }
669 } 666 }
670 667
671 - if (any_warnings) 668 + if (! warnings.empty())
672 { 669 {
  670 + result = false;
673 for (std::list<std::string>::iterator iter = warnings.begin(); 671 for (std::list<std::string>::iterator iter = warnings.begin();
674 iter != warnings.end(); ++iter) 672 iter != warnings.end(); ++iter)
675 { 673 {
676 *this->m->out_stream << "WARNING: " << (*iter) << std::endl; 674 *this->m->out_stream << "WARNING: " << (*iter) << std::endl;
677 } 675 }
678 } 676 }
  677 +
  678 + return result;
679 } 679 }
680 680
681 qpdf_offset_t 681 qpdf_offset_t
@@ -1089,9 +1089,7 @@ QPDF::showLinearizationData() @@ -1089,9 +1089,7 @@ QPDF::showLinearizationData()
1089 try 1089 try
1090 { 1090 {
1091 readLinearizationData(); 1091 readLinearizationData();
1092 - bool errors = false;  
1093 - bool warnings = false;  
1094 - checkLinearizationInternal(errors, warnings); 1092 + checkLinearizationInternal();
1095 dumpLinearizationDataInternal(); 1093 dumpLinearizationDataInternal();
1096 } 1094 }
1097 catch (QPDFExc& e) 1095 catch (QPDFExc& e)
manual/qpdf-manual.xml
@@ -4314,6 +4314,14 @@ print &quot;\n&quot;; @@ -4314,6 +4314,14 @@ print &quot;\n&quot;;
4314 higher level methods for tokenizing content streams. 4314 higher level methods for tokenizing content streams.
4315 </para> 4315 </para>
4316 </listitem> 4316 </listitem>
  4317 + <listitem>
  4318 + <para>
  4319 + When <command>qpdf --check</command> or <command>qpdf
  4320 + --check-linearization</command> encounters a file with
  4321 + linearization warnings but not errors, it now properly exits
  4322 + with exit code 3 instead of 2.
  4323 + </para>
  4324 + </listitem>
4317 </itemizedlist> 4325 </itemizedlist>
4318 </listitem> 4326 </listitem>
4319 <listitem> 4327 <listitem>
@@ -4361,6 +4369,14 @@ print &quot;\n&quot;; @@ -4361,6 +4369,14 @@ print &quot;\n&quot;;
4361 missing /Length keys in the encryption dictionary. 4369 missing /Length keys in the encryption dictionary.
4362 </para> 4370 </para>
4363 </listitem> 4371 </listitem>
  4372 + <listitem>
  4373 + <para>
  4374 + When <command>qpdf --check</command> or <command>qpdf
  4375 + --check-linearization</command> encounters a file with
  4376 + linearization warnings but not errors, it now properly exits
  4377 + with exit code 3 instead of 2.
  4378 + </para>
  4379 + </listitem>
4364 </itemizedlist> 4380 </itemizedlist>
4365 </listitem> 4381 </listitem>
4366 <listitem> 4382 <listitem>
@@ -4462,10 +4478,9 @@ print &quot;\n&quot;; @@ -4462,10 +4478,9 @@ print &quot;\n&quot;;
4462 </listitem> 4478 </listitem>
4463 <listitem> 4479 <listitem>
4464 <para> 4480 <para>
4465 - A new version of  
4466 - <function>QPDF::checkLinearization()</function> has been  
4467 - added that indicates separately whether there were errors or  
4468 - warnings. 4481 + All conditions previously reported by
  4482 + <function>QPDF::checkLinearization()</function> as errors
  4483 + are now presented as warnings.
4469 </para> 4484 </para>
4470 </listitem> 4485 </listitem>
4471 </itemizedlist> 4486 </itemizedlist>
qpdf/qpdf.cc
@@ -3210,15 +3210,10 @@ static void do_check(QPDF&amp; pdf, Options&amp; o, int&amp; exit_code) @@ -3210,15 +3210,10 @@ static void do_check(QPDF&amp; pdf, Options&amp; o, int&amp; exit_code)
3210 if (pdf.isLinearized()) 3210 if (pdf.isLinearized())
3211 { 3211 {
3212 std::cout << "File is linearized\n"; 3212 std::cout << "File is linearized\n";
3213 - bool lin_errors = false;  
3214 - bool lin_warnings = false;  
3215 - // any errors or warnings are reported by checkLinearization()  
3216 - pdf.checkLinearization(lin_errors, lin_warnings);  
3217 - if (lin_errors)  
3218 - {  
3219 - okay = false;  
3220 - }  
3221 - else if (lin_warnings) 3213 + // any errors or warnings are reported by
  3214 + // checkLinearization(). We treat all issues reported here
  3215 + // as warnings.
  3216 + if (! pdf.checkLinearization())
3222 { 3217 {
3223 warnings = true; 3218 warnings = true;
3224 } 3219 }
@@ -3796,22 +3791,15 @@ static void do_inspection(QPDF&amp; pdf, Options&amp; o) @@ -3796,22 +3791,15 @@ static void do_inspection(QPDF&amp; pdf, Options&amp; o)
3796 } 3791 }
3797 if (o.check_linearization) 3792 if (o.check_linearization)
3798 { 3793 {
3799 - bool lin_errors = false;  
3800 - bool lin_warnings = false;  
3801 - pdf.checkLinearization(lin_errors, lin_warnings);  
3802 - if (lin_errors) 3794 + if (pdf.checkLinearization())
3803 { 3795 {
3804 - exit_code = EXIT_ERROR; 3796 + std::cout << o.infilename << ": no linearization errors"
  3797 + << std::endl;
3805 } 3798 }
3806 - else if (lin_warnings && (exit_code != EXIT_ERROR)) 3799 + else if (exit_code != EXIT_ERROR)
3807 { 3800 {
3808 exit_code = EXIT_WARNING; 3801 exit_code = EXIT_WARNING;
3809 } 3802 }
3810 - else  
3811 - {  
3812 - std::cout << o.infilename << ": no linearization errors"  
3813 - << std::endl;  
3814 - }  
3815 } 3803 }
3816 if (o.show_linearization) 3804 if (o.show_linearization)
3817 { 3805 {
qpdf/qtest/qpdf.test
@@ -1321,12 +1321,12 @@ $n_tests += 3; @@ -1321,12 +1321,12 @@ $n_tests += 3;
1321 $td->runtest("bounds check linearization data 1", 1321 $td->runtest("bounds check linearization data 1",
1322 {$td->COMMAND => "qpdf --check linearization-bounds-1.pdf"}, 1322 {$td->COMMAND => "qpdf --check linearization-bounds-1.pdf"},
1323 {$td->FILE => "linearization-bounds-1.out", 1323 {$td->FILE => "linearization-bounds-1.out",
1324 - $td->EXIT_STATUS => 2}, 1324 + $td->EXIT_STATUS => 3},
1325 $td->NORMALIZE_NEWLINES); 1325 $td->NORMALIZE_NEWLINES);
1326 $td->runtest("bounds check linearization data 2", 1326 $td->runtest("bounds check linearization data 2",
1327 {$td->COMMAND => "qpdf --check linearization-bounds-2.pdf"}, 1327 {$td->COMMAND => "qpdf --check linearization-bounds-2.pdf"},
1328 {$td->FILE => "linearization-bounds-2.out", 1328 {$td->FILE => "linearization-bounds-2.out",
1329 - $td->EXIT_STATUS => 2}, 1329 + $td->EXIT_STATUS => 3},
1330 $td->NORMALIZE_NEWLINES); 1330 $td->NORMALIZE_NEWLINES);
1331 # Throws logic error, not bad_alloc 1331 # Throws logic error, not bad_alloc
1332 $td->runtest("sanity check array size", 1332 $td->runtest("sanity check array size",
@@ -2855,7 +2855,7 @@ my @to_linearize = @@ -2855,7 +2855,7 @@ my @to_linearize =
2855 ); 2855 );
2856 2856
2857 $n_tests += @linearized_files + 6; 2857 $n_tests += @linearized_files + 6;
2858 -$n_tests += (3 * @to_linearize * 5) + 8; 2858 +$n_tests += (3 * @to_linearize * 5) + 6;
2859 2859
2860 foreach my $base (@linearized_files) 2860 foreach my $base (@linearized_files)
2861 { 2861 {
@@ -2939,17 +2939,6 @@ foreach my $base (@to_linearize) @@ -2939,17 +2939,6 @@ foreach my $base (@to_linearize)
2939 } 2939 }
2940 } 2940 }
2941 2941
2942 -# Verify that we get proper exit codes for files with only warnings  
2943 -$td->runtest("linearization warnings check",  
2944 - {$td->COMMAND => "qpdf --check lin3.pdf"},  
2945 - {$td->FILE => "lin3-check.out", $td->EXIT_STATUS => 3},  
2946 - $td->NORMALIZE_NEWLINES);  
2947 -$td->runtest("linearization warnings check-linearization",  
2948 - {$td->COMMAND => "qpdf --check-linearization lin3.pdf"},  
2949 - {$td->FILE => "lin3-check-linearization.out",  
2950 - $td->EXIT_STATUS => 3},  
2951 - $td->NORMALIZE_NEWLINES);  
2952 -  
2953 show_ntests(); 2942 show_ntests();
2954 # ---------- 2943 # ----------
2955 $td->notify("--- Encryption Tests ---"); 2944 $td->notify("--- Encryption Tests ---");
qpdf/qtest/qpdf/badlin1.out
1 -ERROR: first page object (/O) mismatch  
2 -ERROR: space before first xref item (/T) mismatch (computed = 11777; file = 11771 1 +WARNING: first page object (/O) mismatch
  2 +WARNING: space before first xref item (/T) mismatch (computed = 11777; file = 11771
3 WARNING: end of first page section (/E) mismatch: /E = 1827; computed = 3889..3891 3 WARNING: end of first page section (/E) mismatch: /E = 1827; computed = 3889..3891
4 WARNING: page 0 has shared identifier entries 4 WARNING: page 0 has shared identifier entries
5 WARNING: page 0: shared object 62: in hint table but not computed list 5 WARNING: page 0: shared object 62: in hint table but not computed list