aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJay Berkenbilt <ejb@ql.org>2017-08-12 13:35:04 +0200
committerJay Berkenbilt <ejb@ql.org>2017-08-12 14:36:36 +0200
commit8249a26d69f72b9cda584c14cc3f12769985e481 (patch)
tree75efa7eeb1899f081e78a10d0bb306d2dfb04531
parent36b3fe5af761b7032a506808cf6ce6d37c297bfc (diff)
downloadqpdf-8249a26d69f72b9cda584c14cc3f12769985e481.tar.zst
Fix infinite loop in QPDFWriter (fixes #143)
-rw-r--r--libqpdf/QPDFWriter.cc9
-rw-r--r--qpdf/qpdf.testcov1
-rw-r--r--qpdf/qtest/qpdf.test1
-rw-r--r--qpdf/qtest/qpdf/issue-143.out19
-rw-r--r--qpdf/qtest/qpdf/issue-143.pdfbin0 -> 707 bytes
5 files changed, 30 insertions, 0 deletions
diff --git a/libqpdf/QPDFWriter.cc b/libqpdf/QPDFWriter.cc
index de4fa349..345613ad 100644
--- a/libqpdf/QPDFWriter.cc
+++ b/libqpdf/QPDFWriter.cc
@@ -1054,6 +1054,9 @@ QPDFWriter::enqueueObject(QPDFObjectHandle object)
// here. Instead, enqueue the object stream. Object
// streams always have generation 0.
int stream_id = this->object_to_object_stream[og];
+ // Detect loops by storing invalid object ID 0, which
+ // will get overwritten later.
+ obj_renumber[og] = 0;
enqueueObject(this->pdf.getObjectByID(stream_id, 0));
}
else
@@ -1079,6 +1082,12 @@ QPDFWriter::enqueueObject(QPDFObjectHandle object)
}
}
}
+ else if (obj_renumber[og] == 0)
+ {
+ // This can happen if a specially constructed file
+ // indicates that an object stream is inside itself.
+ QTC::TC("qpdf", "QPDFWriter ignore self-referential object stream");
+ }
}
else if (object.isArray())
{
diff --git a/qpdf/qpdf.testcov b/qpdf/qpdf.testcov
index 0038aa34..f5b628b9 100644
--- a/qpdf/qpdf.testcov
+++ b/qpdf/qpdf.testcov
@@ -294,3 +294,4 @@ QPDF ignore first extra space in xref entry 0
QPDF ignore second extra space in xref entry 0
QPDF ignore length error xref entry 0
QPDF_encryption pad short parameter 0
+QPDFWriter ignore self-referential object stream 0
diff --git a/qpdf/qtest/qpdf.test b/qpdf/qtest/qpdf.test
index 06f298e0..1aaeb8d4 100644
--- a/qpdf/qtest/qpdf.test
+++ b/qpdf/qtest/qpdf.test
@@ -220,6 +220,7 @@ my @bug_tests = (
["106", "zlib data error", 3],
["141a", "/W entry size 0", 2],
["141b", "/W entry size 0", 2],
+ ["143", "self-referential ostream", 3],
);
$n_tests += scalar(@bug_tests);
foreach my $d (@bug_tests)
diff --git a/qpdf/qtest/qpdf/issue-143.out b/qpdf/qtest/qpdf/issue-143.out
new file mode 100644
index 00000000..2bf1e40d
--- /dev/null
+++ b/qpdf/qtest/qpdf/issue-143.out
@@ -0,0 +1,19 @@
+WARNING: issue-143.pdf: can't find PDF header
+WARNING: issue-143.pdf (xref stream: object 3 0, file position 654): stream keyword not followed by proper line terminator
+WARNING: issue-143.pdf (xref stream: object 3 0, file position 607): stream dictionary lacks /Length key
+WARNING: issue-143.pdf (xref stream: object 3 0, file position 654): attempting to recover stream length
+WARNING: issue-143.pdf (xref stream: object 3 0, file position 654): recovered stream length: 36
+WARNING: issue-143.pdf (xref stream: object 3 0, file position 694): expected endobj
+WARNING: issue-143.pdf: file is damaged
+WARNING: issue-143.pdf (object 1 0, file position 48): expected n n obj
+WARNING: issue-143.pdf: Attempting to reconstruct cross-reference table
+WARNING: issue-143.pdf (file position 24): expected dictionary key but found non-name object; inserting key /QPDFFake1
+WARNING: issue-143.pdf (file position 24): expected dictionary key but found non-name object; inserting key /QPDFFake2
+WARNING: issue-143.pdf (file position 24): expected dictionary key but found non-name object; inserting key /QPDFFake3
+WARNING: issue-143.pdf (file position 24): expected dictionary key but found non-name object; inserting key /QPDFFake4
+WARNING: issue-143.pdf (object 1 0, file position 21): stream dictionary lacks /Length key
+WARNING: issue-143.pdf (object 1 0, file position 84): attempting to recover stream length
+WARNING: issue-143.pdf (object 1 0, file position 84): recovered stream length: 606
+WARNING: issue-143.pdf (object 1 0, file position 694): expected endobj
+WARNING: object stream 1 (file position 33): expected dictionary key but found non-name object; inserting key /QPDFFake1
+qpdf: operation succeeded with warnings; resulting file may have some problems
diff --git a/qpdf/qtest/qpdf/issue-143.pdf b/qpdf/qtest/qpdf/issue-143.pdf
new file mode 100644
index 00000000..b4546036
--- /dev/null
+++ b/qpdf/qtest/qpdf/issue-143.pdf
Binary files differ