Commit 6e3b7982dbcf8087374694253e0e248fbc6c6e3e
1 parent
0109e365
Fix incorrect handling of invalid negative object ids
Fix two errors introduced in #1110 and #1112. Since #1110, encountering the invalid indirect reference #1110 -2147483648 n R produces an integer underflow which, if undetected, immediately trigger a logic error. Since #1112, object -1 0 R may be incorrectly identified as an earlier generation of itself and deleted, invalidating a live iterator.
Showing
5 changed files
with
9 additions
and
5 deletions
fuzz/CMakeLists.txt
| @@ -111,6 +111,8 @@ set(CORPUS_OTHER | @@ -111,6 +111,8 @@ set(CORPUS_OTHER | ||
| 111 | 37740.fuzz | 111 | 37740.fuzz |
| 112 | 57639.fuzz | 112 | 57639.fuzz |
| 113 | 65681.fuzz | 113 | 65681.fuzz |
| 114 | + 65773.fuzz | ||
| 115 | + 65777.fuzz | ||
| 114 | ) | 116 | ) |
| 115 | 117 | ||
| 116 | set(CORPUS_DIR ${CMAKE_CURRENT_BINARY_DIR}/qpdf_corpus) | 118 | set(CORPUS_DIR ${CMAKE_CURRENT_BINARY_DIR}/qpdf_corpus) |
fuzz/qpdf_extra/65773.fuzz
0 → 100644
fuzz/qpdf_extra/65777.fuzz
0 → 100644
No preview for this file type
fuzz/qtest/fuzz.test
| @@ -20,7 +20,7 @@ my @fuzzers = ( | @@ -20,7 +20,7 @@ my @fuzzers = ( | ||
| 20 | ['pngpredictor' => 1], | 20 | ['pngpredictor' => 1], |
| 21 | ['runlength' => 6], | 21 | ['runlength' => 6], |
| 22 | ['tiffpredictor' => 1], | 22 | ['tiffpredictor' => 1], |
| 23 | - ['qpdf' => 54], # increment when adding new files | 23 | + ['qpdf' => 56], # increment when adding new files |
| 24 | ); | 24 | ); |
| 25 | 25 | ||
| 26 | my $n_tests = 0; | 26 | my $n_tests = 0; |
libqpdf/QPDF.cc
| @@ -709,10 +709,11 @@ QPDF::read_xref(qpdf_offset_t xref_offset) | @@ -709,10 +709,11 @@ QPDF::read_xref(qpdf_offset_t xref_offset) | ||
| 709 | 709 | ||
| 710 | // Make sure we keep only the highest generation for any object. | 710 | // Make sure we keep only the highest generation for any object. |
| 711 | QPDFObjGen last_og{-1, 0}; | 711 | QPDFObjGen last_og{-1, 0}; |
| 712 | - for (auto const& og: m->xref_table) { | ||
| 713 | - if (og.first.getObj() == last_og.getObj()) | 712 | + for (auto const& item: m->xref_table) { |
| 713 | + auto id = item.first.getObj(); | ||
| 714 | + if (id == last_og.getObj() && id > 0) | ||
| 714 | removeObject(last_og); | 715 | removeObject(last_og); |
| 715 | - last_og = og.first; | 716 | + last_og = item.first; |
| 716 | } | 717 | } |
| 717 | } | 718 | } |
| 718 | 719 | ||
| @@ -2405,7 +2406,7 @@ QPDF::getCompressibleObjGens() | @@ -2405,7 +2406,7 @@ QPDF::getCompressibleObjGens() | ||
| 2405 | while (!queue.empty()) { | 2406 | while (!queue.empty()) { |
| 2406 | auto obj = queue.back(); | 2407 | auto obj = queue.back(); |
| 2407 | queue.pop_back(); | 2408 | queue.pop_back(); |
| 2408 | - if (obj.isIndirect()) { | 2409 | + if (obj.getObjectID() > 0) { |
| 2409 | QPDFObjGen og = obj.getObjGen(); | 2410 | QPDFObjGen og = obj.getObjGen(); |
| 2410 | const size_t id = toS(og.getObj() - 1); | 2411 | const size_t id = toS(og.getObj() - 1); |
| 2411 | if (id >= max_obj) | 2412 | if (id >= max_obj) |