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,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
  1 +trailer<</Root<<[-2147483648 7 R 8 4 R]>>>>
0 \ No newline at end of file 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,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)