Commit 6e3b7982dbcf8087374694253e0e248fbc6c6e3e

Authored by m-holger
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.
fuzz/CMakeLists.txt
... ... @@ -111,6 +111,8 @@ set(CORPUS_OTHER
111 111 37740.fuzz
112 112 57639.fuzz
113 113 65681.fuzz
  114 + 65773.fuzz
  115 + 65777.fuzz
114 116 )
115 117  
116 118 set(CORPUS_DIR ${CMAKE_CURRENT_BINARY_DIR}/qpdf_corpus)
... ...
fuzz/qpdf_extra/65773.fuzz 0 → 100644
  1 +trailer<</Root<<[-2147483648 7 R 8 4 R]>>>>
0 2 \ No newline at end of file
... ...
fuzz/qpdf_extra/65777.fuzz 0 → 100644
No preview for this file type
fuzz/qtest/fuzz.test
... ... @@ -20,7 +20,7 @@ my @fuzzers = (
20 20 ['pngpredictor' => 1],
21 21 ['runlength' => 6],
22 22 ['tiffpredictor' => 1],
23   - ['qpdf' => 54], # increment when adding new files
  23 + ['qpdf' => 56], # increment when adding new files
24 24 );
25 25  
26 26 my $n_tests = 0;
... ...
libqpdf/QPDF.cc
... ... @@ -709,10 +709,11 @@ QPDF::read_xref(qpdf_offset_t xref_offset)
709 709  
710 710 // Make sure we keep only the highest generation for any object.
711 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 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 2406 while (!queue.empty()) {
2406 2407 auto obj = queue.back();
2407 2408 queue.pop_back();
2408   - if (obj.isIndirect()) {
  2409 + if (obj.getObjectID() > 0) {
2409 2410 QPDFObjGen og = obj.getObjGen();
2410 2411 const size_t id = toS(og.getObj() - 1);
2411 2412 if (id >= max_obj)
... ...