aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fuzz/build.mk1
-rw-r--r--fuzz/qtest/fuzz.test2
-rw-r--r--libqpdf/QPDFWriter.cc14
-rw-r--r--libqpdf/QPDF_Stream.cc3
-rw-r--r--qpdf/qpdf.testcov1
-rw-r--r--qpdf/qtest/qpdf.test6
-rw-r--r--qpdf/qtest/qpdf/fuzz-16214.out22
-rw-r--r--qpdf/qtest/qpdf/fuzz-16214.pdfbin0 -> 12142 bytes
8 files changed, 44 insertions, 5 deletions
diff --git a/fuzz/build.mk b/fuzz/build.mk
index ec3bd61e..d38fb909 100644
--- a/fuzz/build.mk
+++ b/fuzz/build.mk
@@ -41,6 +41,7 @@ CORPUS_FROM_TEST = \
outlines-with-old-root-dests.pdf \
page-labels-and-outlines.pdf \
page-labels-num-tree.pdf \
+ fuzz-16214.pdf \
issue-99b.pdf \
issue-99.pdf \
issue-100.pdf \
diff --git a/fuzz/qtest/fuzz.test b/fuzz/qtest/fuzz.test
index 26ae4f10..df850c45 100644
--- a/fuzz/qtest/fuzz.test
+++ b/fuzz/qtest/fuzz.test
@@ -9,7 +9,7 @@ require TestDriver;
my $td = new TestDriver('fuzz');
-my $qpdf_n_test_files = 29;
+my $qpdf_n_test_files = 30;
my @extra = glob("../qpdf_extra/*.fuzz");
my $qpdf_n_extra_files = scalar(@extra);
my $qpdf_n_orig_files = 2559;
diff --git a/libqpdf/QPDFWriter.cc b/libqpdf/QPDFWriter.cc
index 895f98ce..f5fa2bc9 100644
--- a/libqpdf/QPDFWriter.cc
+++ b/libqpdf/QPDFWriter.cc
@@ -2012,7 +2012,19 @@ QPDFWriter::writeObjectStream(QPDFObjectHandle object)
// pass 1.
indicateProgress(true, false);
}
- writeObject(this->m->pdf.getObjectByObjGen(obj), count);
+ QPDFObjectHandle obj_to_write =
+ this->m->pdf.getObjectByObjGen(obj);
+ if (obj_to_write.isStream())
+ {
+ // This condition occurred in a fuzz input. Ideally we
+ // should block it at at parse time, but it's not
+ // clear to me how to construct a case for this.
+ QTC::TC("qpdf", "QPDFWriter stream in ostream");
+ obj_to_write.warnIfPossible(
+ "stream found inside object stream; treating as null");
+ obj_to_write = QPDFObjectHandle::newNull();
+ }
+ writeObject(obj_to_write, count);
this->m->xref[new_obj] = QPDFXRefEntry(2, new_id, count);
}
diff --git a/libqpdf/QPDF_Stream.cc b/libqpdf/QPDF_Stream.cc
index 4f20c604..dd2796e8 100644
--- a/libqpdf/QPDF_Stream.cc
+++ b/libqpdf/QPDF_Stream.cc
@@ -105,7 +105,8 @@ QPDF_Stream::setStreamDescription()
{
setDescription(
this->qpdf,
- "stream object " + QUtil::int_to_string(this->objid) + " " +
+ this->qpdf->getFilename() +
+ ", stream object " + QUtil::int_to_string(this->objid) + " " +
QUtil::int_to_string(this->generation));
}
diff --git a/qpdf/qpdf.testcov b/qpdf/qpdf.testcov
index c8ad0bdd..f327d464 100644
--- a/qpdf/qpdf.testcov
+++ b/qpdf/qpdf.testcov
@@ -444,3 +444,4 @@ QPDF xref skipped space 0
QPDF eof skipping spaces before xref 1
QPDF_encryption user matches owner V < 5 0
QPDF_encryption same password 1
+QPDFWriter stream in ostream 0
diff --git a/qpdf/qtest/qpdf.test b/qpdf/qtest/qpdf.test
index 00f29c72..41c94519 100644
--- a/qpdf/qtest/qpdf.test
+++ b/qpdf/qtest/qpdf.test
@@ -643,6 +643,7 @@ my @bug_tests = (
["263", "empty xref stream", 2],
["335a", "ozz-fuzz-12152", 2],
["335b", "ozz-fuzz-14845", 2],
+ ["fuzz-16214", "stream in object stream", 3],
# When adding to this list, consider adding to SEED_CORPUS_FILES
# in fuzz/build.mk and updating the count in fuzz/qtest/fuzz.test.
);
@@ -669,9 +670,10 @@ foreach my $d (@bug_tests)
}
else
{
+ my $base = (-f "issue-$n.pdf") ? "issue-$n" : "$n";
$td->runtest($description,
- {$td->COMMAND => "qpdf issue-$n.pdf a.pdf"},
- {$td->FILE => "issue-$n.out",
+ {$td->COMMAND => "qpdf $base.pdf a.pdf"},
+ {$td->FILE => "$base.out",
$td->EXIT_STATUS => $exit_status},
$td->NORMALIZE_NEWLINES);
}
diff --git a/qpdf/qtest/qpdf/fuzz-16214.out b/qpdf/qtest/qpdf/fuzz-16214.out
new file mode 100644
index 00000000..55862b1a
--- /dev/null
+++ b/qpdf/qtest/qpdf/fuzz-16214.out
@@ -0,0 +1,22 @@
+WARNING: fuzz-16214.pdf: can't find PDF header
+WARNING: fuzz-16214.pdf (xref stream: object 5 0, offset 124): stream dictionary lacks /Length key
+WARNING: fuzz-16214.pdf (xref stream: object 5 0, offset 353): attempting to recover stream length
+WARNING: fuzz-16214.pdf (xref stream: object 5 0, offset 353): recovered stream length: 722
+WARNING: fuzz-16214.pdf (xref stream, offset 116): Cross-reference stream data has the wrong size; expected = 92; actual = 196
+WARNING: fuzz-16214.pdf: reported number of objects (6) is not one plus the highest object number (35)
+WARNING: fuzz-16214.pdf (object 14 0, offset 652): expected dictionary key but found non-name object; inserting key /QPDFFake1
+WARNING: fuzz-16214.pdf (object 14 0, offset 734): expected endobj
+WARNING: fuzz-16214.pdf: file is damaged
+WARNING: fuzz-16214.pdf (object 1 0, offset 7189): expected n n obj
+WARNING: fuzz-16214.pdf: Attempting to reconstruct cross-reference table
+WARNING: fuzz-16214.pdf (offset 7207): error decoding stream data for object 2 0: stream inflate: inflate: data: invalid code lengths set
+WARNING: fuzz-16214.pdf (offset 7207): getStreamData called on unfilterable stream
+WARNING: fuzz-16214.pdf (offset 7207): error decoding stream data for object 2 0: stream inflate: inflate: data: invalid code lengths set
+WARNING: fuzz-16214.pdf (offset 7207): getStreamData called on unfilterable stream
+WARNING: fuzz-16214.pdf (object 11 0, offset 11551): supposed object stream 5 has wrong type
+WARNING: fuzz-16214.pdf (object 21 0, offset 3639): expected endstream
+WARNING: fuzz-16214.pdf (object 21 0, offset 3112): attempting to recover stream length
+WARNING: fuzz-16214.pdf (object 21 0, offset 3112): recovered stream length: 340
+WARNING: fuzz-16214.pdf, stream object 8 0: stream found inside object stream; treating as null
+WARNING: fuzz-16214.pdf, stream object 8 0: stream found inside object stream; treating as null
+qpdf: operation succeeded with warnings; resulting file may have some problems
diff --git a/qpdf/qtest/qpdf/fuzz-16214.pdf b/qpdf/qtest/qpdf/fuzz-16214.pdf
new file mode 100644
index 00000000..c84a8eba
--- /dev/null
+++ b/qpdf/qtest/qpdf/fuzz-16214.pdf
Binary files differ