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.
This commit is contained in:
m-holger 2024-01-17 10:39:06 +00:00
parent 0109e365de
commit 6e3b7982db
5 changed files with 9 additions and 5 deletions

View File

@ -111,6 +111,8 @@ set(CORPUS_OTHER
37740.fuzz
57639.fuzz
65681.fuzz
65773.fuzz
65777.fuzz
)
set(CORPUS_DIR ${CMAKE_CURRENT_BINARY_DIR}/qpdf_corpus)

View File

@ -0,0 +1 @@
trailer<</Root<<[-2147483648 7 R 8 4 R]>>>>

BIN
fuzz/qpdf_extra/65777.fuzz Normal file

Binary file not shown.

View File

@ -20,7 +20,7 @@ my @fuzzers = (
['pngpredictor' => 1],
['runlength' => 6],
['tiffpredictor' => 1],
['qpdf' => 54], # increment when adding new files
['qpdf' => 56], # increment when adding new files
);
my $n_tests = 0;

View File

@ -709,10 +709,11 @@ QPDF::read_xref(qpdf_offset_t xref_offset)
// Make sure we keep only the highest generation for any object.
QPDFObjGen last_og{-1, 0};
for (auto const& og: m->xref_table) {
if (og.first.getObj() == last_og.getObj())
for (auto const& item: m->xref_table) {
auto id = item.first.getObj();
if (id == last_og.getObj() && id > 0)
removeObject(last_og);
last_og = og.first;
last_og = item.first;
}
}
@ -2405,7 +2406,7 @@ QPDF::getCompressibleObjGens()
while (!queue.empty()) {
auto obj = queue.back();
queue.pop_back();
if (obj.isIndirect()) {
if (obj.getObjectID() > 0) {
QPDFObjGen og = obj.getObjGen();
const size_t id = toS(og.getObj() - 1);
if (id >= max_obj)