Commit 6ae439f180b300523527038b0537e4c4c2dcac7d

Authored by Jay Berkenbilt
Committed by GitHub
2 parents 8f792b7e e85b98b7

Merge pull request #1194 from m-holger/fuzz

Fix bugs in #1161
fuzz/CMakeLists.txt
@@ -114,6 +114,8 @@ set(CORPUS_OTHER @@ -114,6 +114,8 @@ set(CORPUS_OTHER
114 65681.fuzz 114 65681.fuzz
115 65773.fuzz 115 65773.fuzz
116 65777.fuzz 116 65777.fuzz
  117 + 68374.fuzz
  118 + 68377.fuzz
117 ) 119 )
118 120
119 set(CORPUS_DIR ${CMAKE_CURRENT_BINARY_DIR}/qpdf_corpus) 121 set(CORPUS_DIR ${CMAKE_CURRENT_BINARY_DIR}/qpdf_corpus)
fuzz/qpdf_extra/68374.fuzz 0 → 100644
No preview for this file type
fuzz/qpdf_extra/68377.fuzz 0 → 100644
No preview for this file type
fuzz/qtest/fuzz.test
@@ -21,7 +21,7 @@ my @fuzzers = ( @@ -21,7 +21,7 @@ my @fuzzers = (
21 ['pngpredictor' => 1], 21 ['pngpredictor' => 1],
22 ['runlength' => 6], 22 ['runlength' => 6],
23 ['tiffpredictor' => 2], 23 ['tiffpredictor' => 2],
24 - ['qpdf' => 56], # increment when adding new files 24 + ['qpdf' => 58], # increment when adding new files
25 ); 25 );
26 26
27 my $n_tests = 0; 27 my $n_tests = 0;
libqpdf/QPDF.cc
@@ -1117,8 +1117,7 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle& xref_obj) @@ -1117,8 +1117,7 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle& xref_obj)
1117 if (obj == 0) { 1117 if (obj == 0) {
1118 // This is needed by checkLinearization() 1118 // This is needed by checkLinearization()
1119 m->first_xref_item_offset = xref_offset; 1119 m->first_xref_item_offset = xref_offset;
1120 - }  
1121 - if (fields[0] == 0) { 1120 + } else if (fields[0] == 0) {
1122 // Ignore fields[2], which we don't care about in this case. This works around the issue 1121 // Ignore fields[2], which we don't care about in this case. This works around the issue
1123 // of some PDF files that put invalid values, like -1, here for deleted objects. 1122 // of some PDF files that put invalid values, like -1, here for deleted objects.
1124 insertFreeXrefEntry(QPDFObjGen(obj, 0)); 1123 insertFreeXrefEntry(QPDFObjGen(obj, 0));
@@ -1196,7 +1195,9 @@ QPDF::insertFreeXrefEntry(QPDFObjGen og) @@ -1196,7 +1195,9 @@ QPDF::insertFreeXrefEntry(QPDFObjGen og)
1196 void 1195 void
1197 QPDF::insertReconstructedXrefEntry(int obj, qpdf_offset_t f1, int f2) 1196 QPDF::insertReconstructedXrefEntry(int obj, qpdf_offset_t f1, int f2)
1198 { 1197 {
1199 - if (!(obj > 0 && 0 <= f2 && f2 < 65535)) { 1198 + // Various tables are indexed by object id, with potential size id + 1
  1199 + constexpr static int max_id = std::numeric_limits<int>::max() - 1;
  1200 + if (!(obj > 0 && obj <= max_id && 0 <= f2 && f2 < 65535)) {
1200 QTC::TC("qpdf", "QPDF xref overwrite invalid objgen"); 1201 QTC::TC("qpdf", "QPDF xref overwrite invalid objgen");
1201 return; 1202 return;
1202 } 1203 }
libqpdf/QPDF_optimization.cc
@@ -416,22 +416,26 @@ QPDF::filterCompressedObjects(QPDFWriter::ObjTable const&amp; obj) @@ -416,22 +416,26 @@ QPDF::filterCompressedObjects(QPDFWriter::ObjTable const&amp; obj)
416 ObjUser const& ou = i1.first; 416 ObjUser const& ou = i1.first;
417 // Loop over objects. 417 // Loop over objects.
418 for (auto const& og: i1.second) { 418 for (auto const& og: i1.second) {
419 - if (auto const& i2 = obj[og].object_stream; i2 <= 0) {  
420 - t_obj_user_to_objects[ou].insert(og);  
421 - } else {  
422 - t_obj_user_to_objects[ou].insert(QPDFObjGen(i2, 0)); 419 + if (obj.contains(og)) {
  420 + if (auto const& i2 = obj[og].object_stream; i2 <= 0) {
  421 + t_obj_user_to_objects[ou].insert(og);
  422 + } else {
  423 + t_obj_user_to_objects[ou].insert(QPDFObjGen(i2, 0));
  424 + }
423 } 425 }
424 } 426 }
425 } 427 }
426 428
427 for (auto const& i1: m->object_to_obj_users) { 429 for (auto const& i1: m->object_to_obj_users) {
428 QPDFObjGen const& og = i1.first; 430 QPDFObjGen const& og = i1.first;
429 - // Loop over obj_users.  
430 - for (auto const& ou: i1.second) {  
431 - if (auto i2 = obj[og].object_stream; i2 <= 0) {  
432 - t_object_to_obj_users[og].insert(ou);  
433 - } else {  
434 - t_object_to_obj_users[QPDFObjGen(i2, 0)].insert(ou); 431 + if (obj.contains(og)) {
  432 + // Loop over obj_users.
  433 + for (auto const& ou: i1.second) {
  434 + if (auto i2 = obj[og].object_stream; i2 <= 0) {
  435 + t_object_to_obj_users[og].insert(ou);
  436 + } else {
  437 + t_object_to_obj_users[QPDFObjGen(i2, 0)].insert(ou);
  438 + }
435 } 439 }
436 } 440 }
437 } 441 }
libqpdf/qpdf/ObjTable.hh
@@ -63,6 +63,12 @@ class ObjTable: public std::vector&lt;T&gt; @@ -63,6 +63,12 @@ class ObjTable: public std::vector&lt;T&gt;
63 } 63 }
64 64
65 inline bool 65 inline bool
  66 + contains(QPDFObjGen og) const
  67 + {
  68 + return contains(static_cast<size_t>(og.getObj()));
  69 + }
  70 +
  71 + inline bool
66 contains(QPDFObjectHandle oh) const 72 contains(QPDFObjectHandle oh) const
67 { 73 {
68 return contains(static_cast<size_t>(oh.getObjectID())); 74 return contains(static_cast<size_t>(oh.getObjectID()));