aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJay Berkenbilt <ejb@ql.org>2017-08-12 02:10:28 +0200
committerJay Berkenbilt <ejb@ql.org>2017-08-12 02:11:19 +0200
commit46611f0710fa08f1a90134a84cfccec3a1e49f94 (patch)
tree0c893211acb5929ed3d6572ad2be501029c1a194
parent8fe0b06cd879f503d0e5be63f706d3adda3b8203 (diff)
downloadqpdf-46611f0710fa08f1a90134a84cfccec3a1e49f94.tar.zst
Prevent a division by zero error (fixes #141)
Bad /W in an xref stream could cause a division by zero error. Now this is handled as a special case.
-rw-r--r--libqpdf/QPDF.cc7
-rw-r--r--libqpdf/QPDFWriter.cc4
-rw-r--r--qpdf/qtest/qpdf.test2
-rw-r--r--qpdf/qtest/qpdf/issue-141a.out8
-rw-r--r--qpdf/qtest/qpdf/issue-141a.pdf6
-rw-r--r--qpdf/qtest/qpdf/issue-141b.out5
-rw-r--r--qpdf/qtest/qpdf/issue-141b.pdf6
7 files changed, 38 insertions, 0 deletions
diff --git a/libqpdf/QPDF.cc b/libqpdf/QPDF.cc
index fc0c103f..d1360b14 100644
--- a/libqpdf/QPDF.cc
+++ b/libqpdf/QPDF.cc
@@ -917,6 +917,13 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle& xref_obj)
}
entry_size += W[i];
}
+ if (entry_size == 0)
+ {
+ throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),
+ "xref stream", xref_offset,
+ "Cross-reference stream's /W indicates"
+ " entry size of 0");
+ }
long long max_num_entries =
static_cast<unsigned long long>(-1) / entry_size;
diff --git a/libqpdf/QPDFWriter.cc b/libqpdf/QPDFWriter.cc
index 8ee322af..8d5f0682 100644
--- a/libqpdf/QPDFWriter.cc
+++ b/libqpdf/QPDFWriter.cc
@@ -2056,6 +2056,10 @@ QPDFWriter::generateObjectStreams()
std::vector<QPDFObjGen> const& eligible =
QPDF::Writer::getCompressibleObjGens(this->pdf);
unsigned int n_object_streams = (eligible.size() + 99) / 100;
+ if (n_object_streams == 0)
+ {
+ throw std::logic_error("n_object_streams == 0");
+ }
unsigned int n_per = eligible.size() / n_object_streams;
if (n_per * n_object_streams < eligible.size())
{
diff --git a/qpdf/qtest/qpdf.test b/qpdf/qtest/qpdf.test
index 12fb5dd2..89e41b36 100644
--- a/qpdf/qtest/qpdf.test
+++ b/qpdf/qtest/qpdf.test
@@ -218,6 +218,8 @@ my @bug_tests = (
["119", "other infinite loop", 3],
["120", "other infinite loop", 3],
["106", "zlib data error", 3],
+ ["141a", "/W entry size 0", 2],
+ ["141b", "/W entry size 0", 2],
);
$n_tests += scalar(@bug_tests);
foreach my $d (@bug_tests)
diff --git a/qpdf/qtest/qpdf/issue-141a.out b/qpdf/qtest/qpdf/issue-141a.out
new file mode 100644
index 00000000..6182d90b
--- /dev/null
+++ b/qpdf/qtest/qpdf/issue-141a.out
@@ -0,0 +1,8 @@
+WARNING: issue-141a.pdf: can't find PDF header
+WARNING: issue-141a.pdf (xref stream: object 9 0, file position 10): stream dictionary lacks /Length key
+WARNING: issue-141a.pdf (xref stream: object 9 0, file position 47): attempting to recover stream length
+WARNING: issue-141a.pdf (xref stream: object 9 0, file position 47): unable to recover stream data; treating stream as empty
+WARNING: issue-141a.pdf: file is damaged
+WARNING: issue-141a.pdf (xref stream, file position 3): Cross-reference stream's /W indicates entry size of 0
+WARNING: issue-141a.pdf: Attempting to reconstruct cross-reference table
+issue-141a.pdf: unable to find trailer dictionary while recovering damaged file
diff --git a/qpdf/qtest/qpdf/issue-141a.pdf b/qpdf/qtest/qpdf/issue-141a.pdf
new file mode 100644
index 00000000..dec76be5
--- /dev/null
+++ b/qpdf/qtest/qpdf/issue-141a.pdf
@@ -0,0 +1,6 @@
+0009 0 obj<</Type/XRef/Size 0/W[0 0 0]>>stream
+endstream
+endobj
+startxref
+3
+%%EOF
diff --git a/qpdf/qtest/qpdf/issue-141b.out b/qpdf/qtest/qpdf/issue-141b.out
new file mode 100644
index 00000000..bf591243
--- /dev/null
+++ b/qpdf/qtest/qpdf/issue-141b.out
@@ -0,0 +1,5 @@
+WARNING: issue-141b.pdf: can't find PDF header
+WARNING: issue-141b.pdf: file is damaged
+WARNING: issue-141b.pdf (file position 7): xref not found
+WARNING: issue-141b.pdf: Attempting to reconstruct cross-reference table
+issue-141b.pdf: unable to find trailer dictionary while recovering damaged file
diff --git a/qpdf/qtest/qpdf/issue-141b.pdf b/qpdf/qtest/qpdf/issue-141b.pdf
new file mode 100644
index 00000000..67ce5ab8
--- /dev/null
+++ b/qpdf/qtest/qpdf/issue-141b.pdf
@@ -0,0 +1,6 @@
+%PDF-100 0 obj<</Type/XRef/Size 0/[]/W[0 0 0]/ 0>>stream
+0endstream
+endobj
+startxref
+7
+%%EOF \ No newline at end of file