aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJay Berkenbilt <ejb@ql.org>2024-01-12 13:11:46 +0100
committerJay Berkenbilt <ejb@ql.org>2024-01-12 14:05:22 +0100
commitebb10f3256067c6e4ebea9a21a92d0199ac7fdf9 (patch)
tree5e1d6152bd2cf05f0c0a52e1467cea4dc88df3df
parent2c97aaddd50aacd849bd9d97102d21275fde94a2 (diff)
downloadqpdf-ebb10f3256067c6e4ebea9a21a92d0199ac7fdf9.tar.zst
Fix null pointer issue on array copy
-rw-r--r--fuzz/CMakeLists.txt4
-rw-r--r--fuzz/qpdf_extra/65681.fuzzbin0 -> 60590 bytes
-rw-r--r--fuzz/qtest/fuzz.test2
-rw-r--r--libqpdf/QPDF_Array.cc3
-rw-r--r--qpdf/qpdf.testcov1
-rw-r--r--qpdf/qtest/many-nulls.test6
-rw-r--r--qpdf/test_driver.cc12
7 files changed, 24 insertions, 4 deletions
diff --git a/fuzz/CMakeLists.txt b/fuzz/CMakeLists.txt
index db9bfd71..df1fa807 100644
--- a/fuzz/CMakeLists.txt
+++ b/fuzz/CMakeLists.txt
@@ -109,7 +109,9 @@ set(CORPUS_OTHER
28262.fuzz
30507.fuzz
37740.fuzz
- 57639.fuzz)
+ 57639.fuzz
+ 65681.fuzz
+)
set(CORPUS_DIR ${CMAKE_CURRENT_BINARY_DIR}/qpdf_corpus)
file(MAKE_DIRECTORY ${CORPUS_DIR})
diff --git a/fuzz/qpdf_extra/65681.fuzz b/fuzz/qpdf_extra/65681.fuzz
new file mode 100644
index 00000000..7892f7c0
--- /dev/null
+++ b/fuzz/qpdf_extra/65681.fuzz
Binary files differ
diff --git a/fuzz/qtest/fuzz.test b/fuzz/qtest/fuzz.test
index 26995dac..adce995c 100644
--- a/fuzz/qtest/fuzz.test
+++ b/fuzz/qtest/fuzz.test
@@ -20,7 +20,7 @@ my @fuzzers = (
['pngpredictor' => 1],
['runlength' => 6],
['tiffpredictor' => 1],
- ['qpdf' => 53], # increment when adding new files
+ ['qpdf' => 54], # increment when adding new files
);
my $n_tests = 0;
diff --git a/libqpdf/QPDF_Array.cc b/libqpdf/QPDF_Array.cc
index c8cfe110..7d6f4539 100644
--- a/libqpdf/QPDF_Array.cc
+++ b/libqpdf/QPDF_Array.cc
@@ -1,5 +1,6 @@
#include <qpdf/QPDF_Array.hh>
+#include <qpdf/QTC.hh>
#include <qpdf/QPDFObjectHandle.hh>
#include <qpdf/QPDFObject_private.hh>
@@ -74,8 +75,10 @@ QPDF_Array::copy(bool shallow)
if (shallow) {
return do_create(new QPDF_Array(*this));
} else {
+ QTC::TC("qpdf", "QPDF_Array copy", sp ? 0 : 1);
if (sp) {
auto* result = new QPDF_Array();
+ result->sp = std::make_unique<Sparse>();
result->sp->size = sp->size;
for (auto const& element: sp->elements) {
auto const& obj = element.second;
diff --git a/qpdf/qpdf.testcov b/qpdf/qpdf.testcov
index 397cbf97..6d0f8a4b 100644
--- a/qpdf/qpdf.testcov
+++ b/qpdf/qpdf.testcov
@@ -692,3 +692,4 @@ QPDF recover xref stream 0
QPDFJob misplaced page range 0
QPDFJob duplicated range 0
QPDFJob json over/under no file 0
+QPDF_Array copy 1
diff --git a/qpdf/qtest/many-nulls.test b/qpdf/qtest/many-nulls.test
index 744075f0..8a723d53 100644
--- a/qpdf/qtest/many-nulls.test
+++ b/qpdf/qtest/many-nulls.test
@@ -29,5 +29,9 @@ $td->runtest("run check file",
{$td->COMMAND => "qpdf --check a.pdf"},
{$td->FILE => "many-nulls.out", $td->EXIT_STATUS => 0},
$td->NORMALIZE_NEWLINES);
+$td->runtest("copy sparse array",
+ {$td->COMMAND => "test_driver 97 many-nulls.pdf"},
+ {$td->STRING => "test 97 done\n", $td->EXIT_STATUS => 0},
+ $td->NORMALIZE_NEWLINES);
cleanup();
-$td->report(3);
+$td->report(4);
diff --git a/qpdf/test_driver.cc b/qpdf/test_driver.cc
index 2b8eb761..472a96a1 100644
--- a/qpdf/test_driver.cc
+++ b/qpdf/test_driver.cc
@@ -3366,6 +3366,16 @@ test_96(QPDF& pdf, char const* arg2)
assert(s.unparseBinary() == "<abc0>");
}
+static void
+test_97(QPDF& pdf, char const* arg2)
+{
+ // Shallow array copy. This test uses many-nulls.pdf.
+ auto nulls = pdf.getTrailer().getKey("/Nulls").getArrayItem(0);
+ assert(nulls.isArray() && nulls.getArrayNItems() > 10000);
+ auto nulls2 = nulls.shallowCopy();
+ assert(nulls.unparse() == nulls2.unparse());
+}
+
void
runtest(int n, char const* filename1, char const* arg2)
{
@@ -3467,7 +3477,7 @@ runtest(int n, char const* filename1, char const* arg2)
{78, test_78}, {79, test_79}, {80, test_80}, {81, test_81}, {82, test_82}, {83, test_83},
{84, test_84}, {85, test_85}, {86, test_86}, {87, test_87}, {88, test_88}, {89, test_89},
{90, test_90}, {91, test_91}, {92, test_92}, {93, test_93}, {94, test_94}, {95, test_95},
- {96, test_96}};
+ {96, test_96}, {97, test_97}};
auto fn = test_functions.find(n);
if (fn == test_functions.end()) {