aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog4
-rw-r--r--include/qpdf/QPDF.hh5
-rw-r--r--libqpdf/QPDF_linearization.cc33
-rw-r--r--manual/qpdf-manual.xml16
-rw-r--r--qpdf/qpdf.cc29
-rw-r--r--qpdf/qtest/qpdf.test13
-rw-r--r--qpdf/qtest/qpdf/lin3-check-linearization.out61
-rw-r--r--qpdf/qtest/qpdf/lin3-check.out65
8 files changed, 204 insertions, 22 deletions
diff --git a/ChangeLog b/ChangeLog
index 17e0c973..5d6a0862 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
2019-06-22 Jay Berkenbilt <ejb@ql.org>
+ * When a file has linearization warnings but no errors, qpdf
+ --check and --check-linearization now exit with code 3 instead
+ of 2. Fixes #50.
+
* Add new function QUtil::read_file_into_memory.
2019-06-21 Jay Berkenbilt <ejb@ql.org>
diff --git a/include/qpdf/QPDF.hh b/include/qpdf/QPDF.hh
index f8a84ce9..d534a4df 100644
--- a/include/qpdf/QPDF.hh
+++ b/include/qpdf/QPDF.hh
@@ -483,6 +483,9 @@ class QPDF
// specified in a call to setOutputStreams.
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
@@ -1226,7 +1229,7 @@ class QPDF
// methods to support linearization checking -- implemented in
// QPDF_linearization.cc
void readLinearizationData();
- bool checkLinearizationInternal();
+ void checkLinearizationInternal(bool& errors, bool& warnings);
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 5eb6277e..cb607fed 100644
--- a/libqpdf/QPDF_linearization.cc
+++ b/libqpdf/QPDF_linearization.cc
@@ -65,17 +65,25 @@ load_vector_vector(BitStream& bit_stream,
bool
QPDF::checkLinearization()
{
- bool result = false;
+ bool errors = false;
+ bool warnings = false;
+ checkLinearization(errors, warnings);
+ return (! (errors || warnings));
+}
+
+void
+QPDF::checkLinearization(bool& errors, bool& warnings)
+{
try
{
readLinearizationData();
- result = checkLinearizationInternal();
+ checkLinearizationInternal(errors, warnings);
}
catch (QPDFExc& e)
{
*this->m->out_stream << e.what() << std::endl;
+ errors = true;
}
- return result;
}
bool
@@ -499,8 +507,8 @@ QPDF::readHGeneric(BitStream h, HGeneric& t)
t.group_length = h.getBitsInt(32); // 4
}
-bool
-QPDF::checkLinearizationInternal()
+void
+QPDF::checkLinearizationInternal(bool& any_errors, bool& any_warnings)
{
// All comments referring to the PDF spec refer to the spec for
// version 1.4.
@@ -648,11 +656,11 @@ QPDF::checkLinearizationInternal()
// Report errors
- bool result = true;
+ any_errors = (! errors.empty());
+ any_warnings = (! warnings.empty());
- if (! errors.empty())
+ if (any_errors)
{
- result = false;
for (std::list<std::string>::iterator iter = errors.begin();
iter != errors.end(); ++iter)
{
@@ -660,17 +668,14 @@ QPDF::checkLinearizationInternal()
}
}
- if (! warnings.empty())
+ if (any_warnings)
{
- 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
@@ -1084,7 +1089,9 @@ QPDF::showLinearizationData()
try
{
readLinearizationData();
- checkLinearizationInternal();
+ bool errors = false;
+ bool warnings = false;
+ checkLinearizationInternal(errors, warnings);
dumpLinearizationDataInternal();
}
catch (QPDFExc& e)
diff --git a/manual/qpdf-manual.xml b/manual/qpdf-manual.xml
index 59c452e8..c0cbeb10 100644
--- a/manual/qpdf-manual.xml
+++ b/manual/qpdf-manual.xml
@@ -4329,6 +4329,14 @@ print "\n";
Google's OSS-Fuzz project.
</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>
@@ -4412,6 +4420,14 @@ print "\n";
<function>QUtil::read_file_into_memory</function> was added.
</para>
</listitem>
+ <listitem>
+ <para>
+ A new version of
+ <function>QPDF::checkLinearization()</function> has been
+ added that indicates separately whether there were errors or
+ warnings.
+ </para>
+ </listitem>
</itemizedlist>
</listitem>
<listitem>
diff --git a/qpdf/qpdf.cc b/qpdf/qpdf.cc
index cbda36a1..01dec0fc 100644
--- a/qpdf/qpdf.cc
+++ b/qpdf/qpdf.cc
@@ -3181,6 +3181,7 @@ static void do_check(QPDF& pdf, Options& o, int& exit_code)
// continue to perform additional checks after finding
// errors.
bool okay = true;
+ bool warnings = false;
std::cout << "checking " << o.infilename << std::endl;
try
{
@@ -3196,11 +3197,18 @@ static void do_check(QPDF& pdf, Options& o, int& exit_code)
if (pdf.isLinearized())
{
std::cout << "File is linearized\n";
- if (! pdf.checkLinearization())
+ 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)
{
- // any errors are reported by checkLinearization()
okay = false;
}
+ else if (lin_warnings)
+ {
+ warnings = true;
+ }
}
else
{
@@ -3246,7 +3254,7 @@ static void do_check(QPDF& pdf, Options& o, int& exit_code)
}
if (okay)
{
- if (! pdf.getWarnings().empty())
+ if ((! pdf.getWarnings().empty()) || warnings)
{
exit_code = EXIT_WARNING;
}
@@ -3775,14 +3783,21 @@ static void do_inspection(QPDF& pdf, Options& o)
}
if (o.check_linearization)
{
- if (pdf.checkLinearization())
+ bool lin_errors = false;
+ bool lin_warnings = false;
+ pdf.checkLinearization(lin_errors, lin_warnings);
+ if (lin_errors)
{
- std::cout << o.infilename << ": no linearization errors"
- << std::endl;
+ exit_code = EXIT_ERROR;
+ }
+ else if (lin_warnings && (exit_code != EXIT_ERROR))
+ {
+ exit_code = EXIT_WARNING;
}
else
{
- exit_code = EXIT_ERROR;
+ 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 0069fe4a..e1db8b89 100644
--- a/qpdf/qtest/qpdf.test
+++ b/qpdf/qtest/qpdf.test
@@ -2855,7 +2855,7 @@ my @to_linearize =
);
$n_tests += @linearized_files + 6;
-$n_tests += (3 * @to_linearize * 5) + 6;
+$n_tests += (3 * @to_linearize * 5) + 8;
foreach my $base (@linearized_files)
{
@@ -2939,6 +2939,17 @@ 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/lin3-check-linearization.out b/qpdf/qtest/qpdf/lin3-check-linearization.out
new file mode 100644
index 00000000..b8fda80a
--- /dev/null
+++ b/qpdf/qtest/qpdf/lin3-check-linearization.out
@@ -0,0 +1,61 @@
+WARNING: end of first page section (/E) mismatch: /E = 3978; computed = 3785..3786
+WARNING: page 1: shared object 107: in computed list but not hint table
+WARNING: page 1: shared object 109: in computed list but not hint table
+WARNING: page 2: shared object 107: in computed list but not hint table
+WARNING: page 2: shared object 109: in computed list but not hint table
+WARNING: page 3: shared object 107: in computed list but not hint table
+WARNING: page 3: shared object 109: in computed list but not hint table
+WARNING: page 4: shared object 107: in computed list but not hint table
+WARNING: page 4: shared object 109: in computed list but not hint table
+WARNING: page 5: shared object 107: in computed list but not hint table
+WARNING: page 5: shared object 109: in computed list but not hint table
+WARNING: page 6: shared object 107: in computed list but not hint table
+WARNING: page 6: shared object 109: in computed list but not hint table
+WARNING: page 7: shared object 107: in computed list but not hint table
+WARNING: page 7: shared object 109: in computed list but not hint table
+WARNING: page 8: shared object 107: in computed list but not hint table
+WARNING: page 8: shared object 109: in computed list but not hint table
+WARNING: page 9: shared object 107: in computed list but not hint table
+WARNING: page 9: shared object 109: in computed list but not hint table
+WARNING: page 10: shared object 107: in computed list but not hint table
+WARNING: page 10: shared object 109: in computed list but not hint table
+WARNING: page 11: shared object 107: in computed list but not hint table
+WARNING: page 11: shared object 109: in computed list but not hint table
+WARNING: page 12: shared object 107: in computed list but not hint table
+WARNING: page 12: shared object 109: in computed list but not hint table
+WARNING: page 13: shared object 107: in computed list but not hint table
+WARNING: page 13: shared object 109: in computed list but not hint table
+WARNING: page 14: shared object 107: in computed list but not hint table
+WARNING: page 14: shared object 109: in computed list but not hint table
+WARNING: page 15: shared object 107: in computed list but not hint table
+WARNING: page 15: shared object 109: in computed list but not hint table
+WARNING: page 16: shared object 107: in computed list but not hint table
+WARNING: page 16: shared object 109: in computed list but not hint table
+WARNING: page 17: shared object 107: in computed list but not hint table
+WARNING: page 17: shared object 109: in computed list but not hint table
+WARNING: page 18: shared object 107: in computed list but not hint table
+WARNING: page 18: shared object 109: in computed list but not hint table
+WARNING: page 19: shared object 107: in computed list but not hint table
+WARNING: page 19: shared object 109: in computed list but not hint table
+WARNING: page 20: shared object 107: in computed list but not hint table
+WARNING: page 20: shared object 109: in computed list but not hint table
+WARNING: page 21: shared object 107: in computed list but not hint table
+WARNING: page 21: shared object 109: in computed list but not hint table
+WARNING: page 22: shared object 107: in computed list but not hint table
+WARNING: page 22: shared object 109: in computed list but not hint table
+WARNING: page 23: shared object 107: in computed list but not hint table
+WARNING: page 23: shared object 109: in computed list but not hint table
+WARNING: page 24: shared object 107: in computed list but not hint table
+WARNING: page 24: shared object 109: in computed list but not hint table
+WARNING: page 25: shared object 107: in computed list but not hint table
+WARNING: page 25: shared object 109: in computed list but not hint table
+WARNING: page 26: shared object 107: in computed list but not hint table
+WARNING: page 26: shared object 109: in computed list but not hint table
+WARNING: page 27: shared object 107: in computed list but not hint table
+WARNING: page 27: shared object 109: in computed list but not hint table
+WARNING: page 28: shared object 107: in computed list but not hint table
+WARNING: page 28: shared object 109: in computed list but not hint table
+WARNING: page 29: shared object 107: in computed list but not hint table
+WARNING: page 29: shared object 109: in computed list but not hint table
+WARNING: incorrect offset in outlines table: hint table = 1627; computed = 1547
+WARNING: incorrect length in outlines table: hint table = 1988; computed = 1936
diff --git a/qpdf/qtest/qpdf/lin3-check.out b/qpdf/qtest/qpdf/lin3-check.out
new file mode 100644
index 00000000..ecebb687
--- /dev/null
+++ b/qpdf/qtest/qpdf/lin3-check.out
@@ -0,0 +1,65 @@
+checking lin3.pdf
+PDF Version: 1.3
+File is not encrypted
+File is linearized
+WARNING: end of first page section (/E) mismatch: /E = 3978; computed = 3785..3786
+WARNING: page 1: shared object 107: in computed list but not hint table
+WARNING: page 1: shared object 109: in computed list but not hint table
+WARNING: page 2: shared object 107: in computed list but not hint table
+WARNING: page 2: shared object 109: in computed list but not hint table
+WARNING: page 3: shared object 107: in computed list but not hint table
+WARNING: page 3: shared object 109: in computed list but not hint table
+WARNING: page 4: shared object 107: in computed list but not hint table
+WARNING: page 4: shared object 109: in computed list but not hint table
+WARNING: page 5: shared object 107: in computed list but not hint table
+WARNING: page 5: shared object 109: in computed list but not hint table
+WARNING: page 6: shared object 107: in computed list but not hint table
+WARNING: page 6: shared object 109: in computed list but not hint table
+WARNING: page 7: shared object 107: in computed list but not hint table
+WARNING: page 7: shared object 109: in computed list but not hint table
+WARNING: page 8: shared object 107: in computed list but not hint table
+WARNING: page 8: shared object 109: in computed list but not hint table
+WARNING: page 9: shared object 107: in computed list but not hint table
+WARNING: page 9: shared object 109: in computed list but not hint table
+WARNING: page 10: shared object 107: in computed list but not hint table
+WARNING: page 10: shared object 109: in computed list but not hint table
+WARNING: page 11: shared object 107: in computed list but not hint table
+WARNING: page 11: shared object 109: in computed list but not hint table
+WARNING: page 12: shared object 107: in computed list but not hint table
+WARNING: page 12: shared object 109: in computed list but not hint table
+WARNING: page 13: shared object 107: in computed list but not hint table
+WARNING: page 13: shared object 109: in computed list but not hint table
+WARNING: page 14: shared object 107: in computed list but not hint table
+WARNING: page 14: shared object 109: in computed list but not hint table
+WARNING: page 15: shared object 107: in computed list but not hint table
+WARNING: page 15: shared object 109: in computed list but not hint table
+WARNING: page 16: shared object 107: in computed list but not hint table
+WARNING: page 16: shared object 109: in computed list but not hint table
+WARNING: page 17: shared object 107: in computed list but not hint table
+WARNING: page 17: shared object 109: in computed list but not hint table
+WARNING: page 18: shared object 107: in computed list but not hint table
+WARNING: page 18: shared object 109: in computed list but not hint table
+WARNING: page 19: shared object 107: in computed list but not hint table
+WARNING: page 19: shared object 109: in computed list but not hint table
+WARNING: page 20: shared object 107: in computed list but not hint table
+WARNING: page 20: shared object 109: in computed list but not hint table
+WARNING: page 21: shared object 107: in computed list but not hint table
+WARNING: page 21: shared object 109: in computed list but not hint table
+WARNING: page 22: shared object 107: in computed list but not hint table
+WARNING: page 22: shared object 109: in computed list but not hint table
+WARNING: page 23: shared object 107: in computed list but not hint table
+WARNING: page 23: shared object 109: in computed list but not hint table
+WARNING: page 24: shared object 107: in computed list but not hint table
+WARNING: page 24: shared object 109: in computed list but not hint table
+WARNING: page 25: shared object 107: in computed list but not hint table
+WARNING: page 25: shared object 109: in computed list but not hint table
+WARNING: page 26: shared object 107: in computed list but not hint table
+WARNING: page 26: shared object 109: in computed list but not hint table
+WARNING: page 27: shared object 107: in computed list but not hint table
+WARNING: page 27: shared object 109: in computed list but not hint table
+WARNING: page 28: shared object 107: in computed list but not hint table
+WARNING: page 28: shared object 109: in computed list but not hint table
+WARNING: page 29: shared object 107: in computed list but not hint table
+WARNING: page 29: shared object 109: in computed list but not hint table
+WARNING: incorrect offset in outlines table: hint table = 1627; computed = 1547
+WARNING: incorrect length in outlines table: hint table = 1988; computed = 1936