From 04f45cf652f2ee30a677933817aef8971a1f533d Mon Sep 17 00:00:00 2001 From: Jay Berkenbilt Date: Sun, 23 Jun 2019 09:10:42 -0400 Subject: 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 | 12 +++++------- libqpdf/QPDF_linearization.cc | 40 +++++++++++++++++++--------------------- manual/qpdf-manual.xml | 23 +++++++++++++++++++---- qpdf/qpdf.cc | 28 ++++++++-------------------- qpdf/qtest/qpdf.test | 17 +++-------------- qpdf/qtest/qpdf/badlin1.out | 4 ++-- 6 files changed, 56 insertions(+), 68 deletions(-) diff --git a/include/qpdf/QPDF.hh b/include/qpdf/QPDF.hh index d534a4df..f052cb33 100644 --- a/include/qpdf/QPDF.hh +++ b/include/qpdf/QPDF.hh @@ -477,15 +477,13 @@ class QPDF QPDF_DLL bool isLinearized(); - // Performs various sanity checks on a linearized file. Return - // true if no errors or warnings. Otherwise, return false and + // Performs various sanity checks on a linearized file. Return + // true if no errors or warnings. Otherwise, return false and // output errors and warnings to std::cout or the output stream - // specified in a call to setOutputStreams. + // specified in a call to setOutputStreams. It is recommended for + // linearization errors to be treated as warnings. QPDF_DLL bool checkLinearization(); - // Separately indicate whether there were errors or warnings. - QPDF_DLL - void checkLinearization(bool& errors, bool& warnings); // Calls checkLinearization() and, if possible, prints normalized // contents of some of the hints tables to std::cout or the output @@ -1229,7 +1227,7 @@ class QPDF // methods to support linearization checking -- implemented in // QPDF_linearization.cc void readLinearizationData(); - void checkLinearizationInternal(bool& errors, bool& warnings); + bool checkLinearizationInternal(); void dumpLinearizationDataInternal(); QPDFObjectHandle readHintStream( Pipeline&, qpdf_offset_t offset, size_t length); diff --git a/libqpdf/QPDF_linearization.cc b/libqpdf/QPDF_linearization.cc index cb607fed..15e02ad1 100644 --- a/libqpdf/QPDF_linearization.cc +++ b/libqpdf/QPDF_linearization.cc @@ -65,25 +65,17 @@ load_vector_vector(BitStream& bit_stream, bool QPDF::checkLinearization() { - bool errors = false; - bool warnings = false; - checkLinearization(errors, warnings); - return (! (errors || warnings)); -} - -void -QPDF::checkLinearization(bool& errors, bool& warnings) -{ + bool result = false; try { readLinearizationData(); - checkLinearizationInternal(errors, warnings); + result = checkLinearizationInternal(); } catch (QPDFExc& e) { *this->m->out_stream << e.what() << std::endl; - errors = true; } + return result; } bool @@ -507,8 +499,8 @@ QPDF::readHGeneric(BitStream h, HGeneric& t) t.group_length = h.getBitsInt(32); // 4 } -void -QPDF::checkLinearizationInternal(bool& any_errors, bool& any_warnings) +bool +QPDF::checkLinearizationInternal() { // All comments referring to the PDF spec refer to the spec for // version 1.4. @@ -656,26 +648,34 @@ QPDF::checkLinearizationInternal(bool& any_errors, bool& any_warnings) // Report errors - any_errors = (! errors.empty()); - any_warnings = (! warnings.empty()); + bool result = true; - if (any_errors) + // Treat all linearization errors as warnings. Many of them occur + // in otherwise working files, so it's really misleading to treat + // them as errors. We'll hang onto the distinction in the code for + // now in case we ever have a chance to clean up the linearization + // code. + if (! errors.empty()) { + result = false; for (std::list::iterator iter = errors.begin(); iter != errors.end(); ++iter) { - *this->m->out_stream << "ERROR: " << (*iter) << std::endl; + *this->m->out_stream << "WARNING: " << (*iter) << std::endl; } } - if (any_warnings) + if (! warnings.empty()) { + result = false; for (std::list::iterator iter = warnings.begin(); iter != warnings.end(); ++iter) { *this->m->out_stream << "WARNING: " << (*iter) << std::endl; } } + + return result; } qpdf_offset_t @@ -1089,9 +1089,7 @@ QPDF::showLinearizationData() try { readLinearizationData(); - bool errors = false; - bool warnings = false; - checkLinearizationInternal(errors, warnings); + checkLinearizationInternal(); dumpLinearizationDataInternal(); } catch (QPDFExc& e) diff --git a/manual/qpdf-manual.xml b/manual/qpdf-manual.xml index 26ccfeea..d991a611 100644 --- a/manual/qpdf-manual.xml +++ b/manual/qpdf-manual.xml @@ -4314,6 +4314,14 @@ print "\n"; higher level methods for tokenizing content streams. + + + When qpdf --check or qpdf + --check-linearization encounters a file with + linearization warnings but not errors, it now properly exits + with exit code 3 instead of 2. + + @@ -4361,6 +4369,14 @@ print "\n"; missing /Length keys in the encryption dictionary. + + + When qpdf --check or qpdf + --check-linearization encounters a file with + linearization warnings but not errors, it now properly exits + with exit code 3 instead of 2. + + @@ -4462,10 +4478,9 @@ print "\n"; - A new version of - QPDF::checkLinearization() has been - added that indicates separately whether there were errors or - warnings. + All conditions previously reported by + QPDF::checkLinearization() as errors + are now presented as warnings. diff --git a/qpdf/qpdf.cc b/qpdf/qpdf.cc index 8f83317b..da37ac25 100644 --- a/qpdf/qpdf.cc +++ b/qpdf/qpdf.cc @@ -3210,15 +3210,10 @@ static void do_check(QPDF& pdf, Options& o, int& exit_code) if (pdf.isLinearized()) { std::cout << "File is linearized\n"; - bool lin_errors = false; - bool lin_warnings = false; - // any errors or warnings are reported by checkLinearization() - pdf.checkLinearization(lin_errors, lin_warnings); - if (lin_errors) - { - okay = false; - } - else if (lin_warnings) + // any errors or warnings are reported by + // checkLinearization(). We treat all issues reported here + // as warnings. + if (! pdf.checkLinearization()) { warnings = true; } @@ -3796,22 +3791,15 @@ static void do_inspection(QPDF& pdf, Options& o) } if (o.check_linearization) { - bool lin_errors = false; - bool lin_warnings = false; - pdf.checkLinearization(lin_errors, lin_warnings); - if (lin_errors) + if (pdf.checkLinearization()) { - exit_code = EXIT_ERROR; + std::cout << o.infilename << ": no linearization errors" + << std::endl; } - else if (lin_warnings && (exit_code != EXIT_ERROR)) + else if (exit_code != EXIT_ERROR) { exit_code = EXIT_WARNING; } - else - { - std::cout << o.infilename << ": no linearization errors" - << std::endl; - } } if (o.show_linearization) { diff --git a/qpdf/qtest/qpdf.test b/qpdf/qtest/qpdf.test index 0329d35a..a11ccd0b 100644 --- a/qpdf/qtest/qpdf.test +++ b/qpdf/qtest/qpdf.test @@ -1321,12 +1321,12 @@ $n_tests += 3; $td->runtest("bounds check linearization data 1", {$td->COMMAND => "qpdf --check linearization-bounds-1.pdf"}, {$td->FILE => "linearization-bounds-1.out", - $td->EXIT_STATUS => 2}, + $td->EXIT_STATUS => 3}, $td->NORMALIZE_NEWLINES); $td->runtest("bounds check linearization data 2", {$td->COMMAND => "qpdf --check linearization-bounds-2.pdf"}, {$td->FILE => "linearization-bounds-2.out", - $td->EXIT_STATUS => 2}, + $td->EXIT_STATUS => 3}, $td->NORMALIZE_NEWLINES); # Throws logic error, not bad_alloc $td->runtest("sanity check array size", @@ -2855,7 +2855,7 @@ my @to_linearize = ); $n_tests += @linearized_files + 6; -$n_tests += (3 * @to_linearize * 5) + 8; +$n_tests += (3 * @to_linearize * 5) + 6; foreach my $base (@linearized_files) { @@ -2939,17 +2939,6 @@ foreach my $base (@to_linearize) } } -# Verify that we get proper exit codes for files with only warnings -$td->runtest("linearization warnings check", - {$td->COMMAND => "qpdf --check lin3.pdf"}, - {$td->FILE => "lin3-check.out", $td->EXIT_STATUS => 3}, - $td->NORMALIZE_NEWLINES); -$td->runtest("linearization warnings check-linearization", - {$td->COMMAND => "qpdf --check-linearization lin3.pdf"}, - {$td->FILE => "lin3-check-linearization.out", - $td->EXIT_STATUS => 3}, - $td->NORMALIZE_NEWLINES); - show_ntests(); # ---------- $td->notify("--- Encryption Tests ---"); diff --git a/qpdf/qtest/qpdf/badlin1.out b/qpdf/qtest/qpdf/badlin1.out index 8ad4bfd5..e61a201f 100644 --- a/qpdf/qtest/qpdf/badlin1.out +++ b/qpdf/qtest/qpdf/badlin1.out @@ -1,5 +1,5 @@ -ERROR: first page object (/O) mismatch -ERROR: space before first xref item (/T) mismatch (computed = 11777; file = 11771 +WARNING: first page object (/O) mismatch +WARNING: space before first xref item (/T) mismatch (computed = 11777; file = 11771 WARNING: end of first page section (/E) mismatch: /E = 1827; computed = 3889..3891 WARNING: page 0 has shared identifier entries WARNING: page 0: shared object 62: in hint table but not computed list -- cgit v1.2.3-54-g00ecf