Commit ebb10f3256067c6e4ebea9a21a92d0199ac7fdf9
1 parent
2c97aadd
Fix null pointer issue on array copy
Showing
7 changed files
with
24 additions
and
4 deletions
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->runtest("run check file", | @@ -29,5 +29,9 @@ $td->runtest("run check file", | ||
| 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& pdf, char const* arg2) | @@ -3366,6 +3366,16 @@ test_96(QPDF& 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()) { |