Skip to content

Commit

Permalink
Treat all linearization errors as warnings
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
jberkenbilt committed Jun 23, 2019
1 parent 0b45dfd commit 04f45cf
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 68 deletions.
12 changes: 5 additions & 7 deletions include/qpdf/QPDF.hh
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand Down
40 changes: 19 additions & 21 deletions libqpdf/QPDF_linearization.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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<std::string>::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<std::string>::iterator iter = warnings.begin();
iter != warnings.end(); ++iter)
{
*this->m->out_stream << "WARNING: " << (*iter) << std::endl;
}
}

return result;
}

qpdf_offset_t
Expand Down Expand Up @@ -1089,9 +1089,7 @@ QPDF::showLinearizationData()
try
{
readLinearizationData();
bool errors = false;
bool warnings = false;
checkLinearizationInternal(errors, warnings);
checkLinearizationInternal();
dumpLinearizationDataInternal();
}
catch (QPDFExc& e)
Expand Down
23 changes: 19 additions & 4 deletions manual/qpdf-manual.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4314,6 +4314,14 @@ print "\n";
higher level methods for tokenizing content streams.
</para>
</listitem>
<listitem>
<para>
When <command>qpdf --check</command> or <command>qpdf
--check-linearization</command> encounters a file with
linearization warnings but not errors, it now properly exits
with exit code 3 instead of 2.
</para>
</listitem>
</itemizedlist>
</listitem>
<listitem>
Expand Down Expand Up @@ -4361,6 +4369,14 @@ print "\n";
missing /Length keys in the encryption dictionary.
</para>
</listitem>
<listitem>
<para>
When <command>qpdf --check</command> or <command>qpdf
--check-linearization</command> encounters a file with
linearization warnings but not errors, it now properly exits
with exit code 3 instead of 2.
</para>
</listitem>
</itemizedlist>
</listitem>
<listitem>
Expand Down Expand Up @@ -4462,10 +4478,9 @@ print "\n";
</listitem>
<listitem>
<para>
A new version of
<function>QPDF::checkLinearization()</function> has been
added that indicates separately whether there were errors or
warnings.
All conditions previously reported by
<function>QPDF::checkLinearization()</function> as errors
are now presented as warnings.
</para>
</listitem>
</itemizedlist>
Expand Down
28 changes: 8 additions & 20 deletions qpdf/qpdf.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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)
{
Expand Down
17 changes: 3 additions & 14 deletions qpdf/qtest/qpdf.test
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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 ---");
Expand Down
4 changes: 2 additions & 2 deletions qpdf/qtest/qpdf/badlin1.out
Original file line number Diff line number Diff line change
@@ -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
Expand Down

0 comments on commit 04f45cf

Please sign in to comment.