Commit 46611f0710fa08f1a90134a84cfccec3a1e49f94
1 parent
8fe0b06c
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.
Showing
7 changed files
with
38 additions
and
0 deletions
libqpdf/QPDF.cc
| ... | ... | @@ -917,6 +917,13 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle& xref_obj) |
| 917 | 917 | } |
| 918 | 918 | entry_size += W[i]; |
| 919 | 919 | } |
| 920 | + if (entry_size == 0) | |
| 921 | + { | |
| 922 | + throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), | |
| 923 | + "xref stream", xref_offset, | |
| 924 | + "Cross-reference stream's /W indicates" | |
| 925 | + " entry size of 0"); | |
| 926 | + } | |
| 920 | 927 | long long max_num_entries = |
| 921 | 928 | static_cast<unsigned long long>(-1) / entry_size; |
| 922 | 929 | ... | ... |
libqpdf/QPDFWriter.cc
| ... | ... | @@ -2056,6 +2056,10 @@ QPDFWriter::generateObjectStreams() |
| 2056 | 2056 | std::vector<QPDFObjGen> const& eligible = |
| 2057 | 2057 | QPDF::Writer::getCompressibleObjGens(this->pdf); |
| 2058 | 2058 | unsigned int n_object_streams = (eligible.size() + 99) / 100; |
| 2059 | + if (n_object_streams == 0) | |
| 2060 | + { | |
| 2061 | + throw std::logic_error("n_object_streams == 0"); | |
| 2062 | + } | |
| 2059 | 2063 | unsigned int n_per = eligible.size() / n_object_streams; |
| 2060 | 2064 | if (n_per * n_object_streams < eligible.size()) |
| 2061 | 2065 | { | ... | ... |
qpdf/qtest/qpdf.test
| ... | ... | @@ -218,6 +218,8 @@ my @bug_tests = ( |
| 218 | 218 | ["119", "other infinite loop", 3], |
| 219 | 219 | ["120", "other infinite loop", 3], |
| 220 | 220 | ["106", "zlib data error", 3], |
| 221 | + ["141a", "/W entry size 0", 2], | |
| 222 | + ["141b", "/W entry size 0", 2], | |
| 221 | 223 | ); |
| 222 | 224 | $n_tests += scalar(@bug_tests); |
| 223 | 225 | foreach my $d (@bug_tests) | ... | ... |
qpdf/qtest/qpdf/issue-141a.out
0 → 100644
| 1 | +WARNING: issue-141a.pdf: can't find PDF header | |
| 2 | +WARNING: issue-141a.pdf (xref stream: object 9 0, file position 10): stream dictionary lacks /Length key | |
| 3 | +WARNING: issue-141a.pdf (xref stream: object 9 0, file position 47): attempting to recover stream length | |
| 4 | +WARNING: issue-141a.pdf (xref stream: object 9 0, file position 47): unable to recover stream data; treating stream as empty | |
| 5 | +WARNING: issue-141a.pdf: file is damaged | |
| 6 | +WARNING: issue-141a.pdf (xref stream, file position 3): Cross-reference stream's /W indicates entry size of 0 | |
| 7 | +WARNING: issue-141a.pdf: Attempting to reconstruct cross-reference table | |
| 8 | +issue-141a.pdf: unable to find trailer dictionary while recovering damaged file | ... | ... |
qpdf/qtest/qpdf/issue-141a.pdf
0 → 100644
qpdf/qtest/qpdf/issue-141b.out
0 → 100644
| 1 | +WARNING: issue-141b.pdf: can't find PDF header | |
| 2 | +WARNING: issue-141b.pdf: file is damaged | |
| 3 | +WARNING: issue-141b.pdf (file position 7): xref not found | |
| 4 | +WARNING: issue-141b.pdf: Attempting to reconstruct cross-reference table | |
| 5 | +issue-141b.pdf: unable to find trailer dictionary while recovering damaged file | ... | ... |