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,6 +917,13 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle& xref_obj) | ||
| 917 | } | 917 | } |
| 918 | entry_size += W[i]; | 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 | long long max_num_entries = | 927 | long long max_num_entries = |
| 921 | static_cast<unsigned long long>(-1) / entry_size; | 928 | static_cast<unsigned long long>(-1) / entry_size; |
| 922 | 929 |
libqpdf/QPDFWriter.cc
| @@ -2056,6 +2056,10 @@ QPDFWriter::generateObjectStreams() | @@ -2056,6 +2056,10 @@ QPDFWriter::generateObjectStreams() | ||
| 2056 | std::vector<QPDFObjGen> const& eligible = | 2056 | std::vector<QPDFObjGen> const& eligible = |
| 2057 | QPDF::Writer::getCompressibleObjGens(this->pdf); | 2057 | QPDF::Writer::getCompressibleObjGens(this->pdf); |
| 2058 | unsigned int n_object_streams = (eligible.size() + 99) / 100; | 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 | unsigned int n_per = eligible.size() / n_object_streams; | 2063 | unsigned int n_per = eligible.size() / n_object_streams; |
| 2060 | if (n_per * n_object_streams < eligible.size()) | 2064 | if (n_per * n_object_streams < eligible.size()) |
| 2061 | { | 2065 | { |
qpdf/qtest/qpdf.test
| @@ -218,6 +218,8 @@ my @bug_tests = ( | @@ -218,6 +218,8 @@ my @bug_tests = ( | ||
| 218 | ["119", "other infinite loop", 3], | 218 | ["119", "other infinite loop", 3], |
| 219 | ["120", "other infinite loop", 3], | 219 | ["120", "other infinite loop", 3], |
| 220 | ["106", "zlib data error", 3], | 220 | ["106", "zlib data error", 3], |
| 221 | + ["141a", "/W entry size 0", 2], | ||
| 222 | + ["141b", "/W entry size 0", 2], | ||
| 221 | ); | 223 | ); |
| 222 | $n_tests += scalar(@bug_tests); | 224 | $n_tests += scalar(@bug_tests); |
| 223 | foreach my $d (@bug_tests) | 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 |