Commit ebb10f3256067c6e4ebea9a21a92d0199ac7fdf9

Authored by Jay Berkenbilt
1 parent 2c97aadd

Fix null pointer issue on array copy

fuzz/CMakeLists.txt
@@ -109,7 +109,9 @@ set(CORPUS_OTHER @@ -109,7 +109,9 @@ set(CORPUS_OTHER
109 28262.fuzz 109 28262.fuzz
110 30507.fuzz 110 30507.fuzz
111 37740.fuzz 111 37740.fuzz
112 - 57639.fuzz) 112 + 57639.fuzz
  113 + 65681.fuzz
  114 +)
113 115
114 set(CORPUS_DIR ${CMAKE_CURRENT_BINARY_DIR}/qpdf_corpus) 116 set(CORPUS_DIR ${CMAKE_CURRENT_BINARY_DIR}/qpdf_corpus)
115 file(MAKE_DIRECTORY ${CORPUS_DIR}) 117 file(MAKE_DIRECTORY ${CORPUS_DIR})
fuzz/qpdf_extra/65681.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' => 53], # increment when adding new files 23 + ['qpdf' => 54], # increment when adding new files
24 ); 24 );
25 25
26 my $n_tests = 0; 26 my $n_tests = 0;
libqpdf/QPDF_Array.cc
1 #include <qpdf/QPDF_Array.hh> 1 #include <qpdf/QPDF_Array.hh>
2 2
  3 +#include <qpdf/QTC.hh>
3 #include <qpdf/QPDFObjectHandle.hh> 4 #include <qpdf/QPDFObjectHandle.hh>
4 #include <qpdf/QPDFObject_private.hh> 5 #include <qpdf/QPDFObject_private.hh>
5 6
@@ -74,8 +75,10 @@ QPDF_Array::copy(bool shallow) @@ -74,8 +75,10 @@ QPDF_Array::copy(bool shallow)
74 if (shallow) { 75 if (shallow) {
75 return do_create(new QPDF_Array(*this)); 76 return do_create(new QPDF_Array(*this));
76 } else { 77 } else {
  78 + QTC::TC("qpdf", "QPDF_Array copy", sp ? 0 : 1);
77 if (sp) { 79 if (sp) {
78 auto* result = new QPDF_Array(); 80 auto* result = new QPDF_Array();
  81 + result->sp = std::make_unique<Sparse>();
79 result->sp->size = sp->size; 82 result->sp->size = sp->size;
80 for (auto const& element: sp->elements) { 83 for (auto const& element: sp->elements) {
81 auto const& obj = element.second; 84 auto const& obj = element.second;
qpdf/qpdf.testcov
@@ -692,3 +692,4 @@ QPDF recover xref stream 0 @@ -692,3 +692,4 @@ QPDF recover xref stream 0
692 QPDFJob misplaced page range 0 692 QPDFJob misplaced page range 0
693 QPDFJob duplicated range 0 693 QPDFJob duplicated range 0
694 QPDFJob json over/under no file 0 694 QPDFJob json over/under no file 0
  695 +QPDF_Array copy 1
qpdf/qtest/many-nulls.test
@@ -29,5 +29,9 @@ $td-&gt;runtest(&quot;run check file&quot;, @@ -29,5 +29,9 @@ $td-&gt;runtest(&quot;run check file&quot;,
29 {$td->COMMAND => "qpdf --check a.pdf"}, 29 {$td->COMMAND => "qpdf --check a.pdf"},
30 {$td->FILE => "many-nulls.out", $td->EXIT_STATUS => 0}, 30 {$td->FILE => "many-nulls.out", $td->EXIT_STATUS => 0},
31 $td->NORMALIZE_NEWLINES); 31 $td->NORMALIZE_NEWLINES);
  32 +$td->runtest("copy sparse array",
  33 + {$td->COMMAND => "test_driver 97 many-nulls.pdf"},
  34 + {$td->STRING => "test 97 done\n", $td->EXIT_STATUS => 0},
  35 + $td->NORMALIZE_NEWLINES);
32 cleanup(); 36 cleanup();
33 -$td->report(3); 37 +$td->report(4);
qpdf/test_driver.cc
@@ -3366,6 +3366,16 @@ test_96(QPDF&amp; pdf, char const* arg2) @@ -3366,6 +3366,16 @@ test_96(QPDF&amp; pdf, char const* arg2)
3366 assert(s.unparseBinary() == "<abc0>"); 3366 assert(s.unparseBinary() == "<abc0>");
3367 } 3367 }
3368 3368
  3369 +static void
  3370 +test_97(QPDF& pdf, char const* arg2)
  3371 +{
  3372 + // Shallow array copy. This test uses many-nulls.pdf.
  3373 + auto nulls = pdf.getTrailer().getKey("/Nulls").getArrayItem(0);
  3374 + assert(nulls.isArray() && nulls.getArrayNItems() > 10000);
  3375 + auto nulls2 = nulls.shallowCopy();
  3376 + assert(nulls.unparse() == nulls2.unparse());
  3377 +}
  3378 +
3369 void 3379 void
3370 runtest(int n, char const* filename1, char const* arg2) 3380 runtest(int n, char const* filename1, char const* arg2)
3371 { 3381 {
@@ -3467,7 +3477,7 @@ runtest(int n, char const* filename1, char const* arg2) @@ -3467,7 +3477,7 @@ runtest(int n, char const* filename1, char const* arg2)
3467 {78, test_78}, {79, test_79}, {80, test_80}, {81, test_81}, {82, test_82}, {83, test_83}, 3477 {78, test_78}, {79, test_79}, {80, test_80}, {81, test_81}, {82, test_82}, {83, test_83},
3468 {84, test_84}, {85, test_85}, {86, test_86}, {87, test_87}, {88, test_88}, {89, test_89}, 3478 {84, test_84}, {85, test_85}, {86, test_86}, {87, test_87}, {88, test_88}, {89, test_89},
3469 {90, test_90}, {91, test_91}, {92, test_92}, {93, test_93}, {94, test_94}, {95, test_95}, 3479 {90, test_90}, {91, test_91}, {92, test_92}, {93, test_93}, {94, test_94}, {95, test_95},
3470 - {96, test_96}}; 3480 + {96, test_96}, {97, test_97}};
3471 3481
3472 auto fn = test_functions.find(n); 3482 auto fn = test_functions.find(n);
3473 if (fn == test_functions.end()) { 3483 if (fn == test_functions.end()) {