Commit 8249a26d69f72b9cda584c14cc3f12769985e481
1 parent
36b3fe5a
Fix infinite loop in QPDFWriter (fixes #143)
Showing
5 changed files
with
30 additions
and
0 deletions
libqpdf/QPDFWriter.cc
| @@ -1054,6 +1054,9 @@ QPDFWriter::enqueueObject(QPDFObjectHandle object) | @@ -1054,6 +1054,9 @@ QPDFWriter::enqueueObject(QPDFObjectHandle object) | ||
| 1054 | // here. Instead, enqueue the object stream. Object | 1054 | // here. Instead, enqueue the object stream. Object |
| 1055 | // streams always have generation 0. | 1055 | // streams always have generation 0. |
| 1056 | int stream_id = this->object_to_object_stream[og]; | 1056 | int stream_id = this->object_to_object_stream[og]; |
| 1057 | + // Detect loops by storing invalid object ID 0, which | ||
| 1058 | + // will get overwritten later. | ||
| 1059 | + obj_renumber[og] = 0; | ||
| 1057 | enqueueObject(this->pdf.getObjectByID(stream_id, 0)); | 1060 | enqueueObject(this->pdf.getObjectByID(stream_id, 0)); |
| 1058 | } | 1061 | } |
| 1059 | else | 1062 | else |
| @@ -1079,6 +1082,12 @@ QPDFWriter::enqueueObject(QPDFObjectHandle object) | @@ -1079,6 +1082,12 @@ QPDFWriter::enqueueObject(QPDFObjectHandle object) | ||
| 1079 | } | 1082 | } |
| 1080 | } | 1083 | } |
| 1081 | } | 1084 | } |
| 1085 | + else if (obj_renumber[og] == 0) | ||
| 1086 | + { | ||
| 1087 | + // This can happen if a specially constructed file | ||
| 1088 | + // indicates that an object stream is inside itself. | ||
| 1089 | + QTC::TC("qpdf", "QPDFWriter ignore self-referential object stream"); | ||
| 1090 | + } | ||
| 1082 | } | 1091 | } |
| 1083 | else if (object.isArray()) | 1092 | else if (object.isArray()) |
| 1084 | { | 1093 | { |
qpdf/qpdf.testcov
| @@ -294,3 +294,4 @@ QPDF ignore first extra space in xref entry 0 | @@ -294,3 +294,4 @@ QPDF ignore first extra space in xref entry 0 | ||
| 294 | QPDF ignore second extra space in xref entry 0 | 294 | QPDF ignore second extra space in xref entry 0 |
| 295 | QPDF ignore length error xref entry 0 | 295 | QPDF ignore length error xref entry 0 |
| 296 | QPDF_encryption pad short parameter 0 | 296 | QPDF_encryption pad short parameter 0 |
| 297 | +QPDFWriter ignore self-referential object stream 0 |
qpdf/qtest/qpdf.test
| @@ -220,6 +220,7 @@ my @bug_tests = ( | @@ -220,6 +220,7 @@ my @bug_tests = ( | ||
| 220 | ["106", "zlib data error", 3], | 220 | ["106", "zlib data error", 3], |
| 221 | ["141a", "/W entry size 0", 2], | 221 | ["141a", "/W entry size 0", 2], |
| 222 | ["141b", "/W entry size 0", 2], | 222 | ["141b", "/W entry size 0", 2], |
| 223 | + ["143", "self-referential ostream", 3], | ||
| 223 | ); | 224 | ); |
| 224 | $n_tests += scalar(@bug_tests); | 225 | $n_tests += scalar(@bug_tests); |
| 225 | foreach my $d (@bug_tests) | 226 | foreach my $d (@bug_tests) |
qpdf/qtest/qpdf/issue-143.out
0 → 100644
| 1 | +WARNING: issue-143.pdf: can't find PDF header | ||
| 2 | +WARNING: issue-143.pdf (xref stream: object 3 0, file position 654): stream keyword not followed by proper line terminator | ||
| 3 | +WARNING: issue-143.pdf (xref stream: object 3 0, file position 607): stream dictionary lacks /Length key | ||
| 4 | +WARNING: issue-143.pdf (xref stream: object 3 0, file position 654): attempting to recover stream length | ||
| 5 | +WARNING: issue-143.pdf (xref stream: object 3 0, file position 654): recovered stream length: 36 | ||
| 6 | +WARNING: issue-143.pdf (xref stream: object 3 0, file position 694): expected endobj | ||
| 7 | +WARNING: issue-143.pdf: file is damaged | ||
| 8 | +WARNING: issue-143.pdf (object 1 0, file position 48): expected n n obj | ||
| 9 | +WARNING: issue-143.pdf: Attempting to reconstruct cross-reference table | ||
| 10 | +WARNING: issue-143.pdf (file position 24): expected dictionary key but found non-name object; inserting key /QPDFFake1 | ||
| 11 | +WARNING: issue-143.pdf (file position 24): expected dictionary key but found non-name object; inserting key /QPDFFake2 | ||
| 12 | +WARNING: issue-143.pdf (file position 24): expected dictionary key but found non-name object; inserting key /QPDFFake3 | ||
| 13 | +WARNING: issue-143.pdf (file position 24): expected dictionary key but found non-name object; inserting key /QPDFFake4 | ||
| 14 | +WARNING: issue-143.pdf (object 1 0, file position 21): stream dictionary lacks /Length key | ||
| 15 | +WARNING: issue-143.pdf (object 1 0, file position 84): attempting to recover stream length | ||
| 16 | +WARNING: issue-143.pdf (object 1 0, file position 84): recovered stream length: 606 | ||
| 17 | +WARNING: issue-143.pdf (object 1 0, file position 694): expected endobj | ||
| 18 | +WARNING: object stream 1 (file position 33): expected dictionary key but found non-name object; inserting key /QPDFFake1 | ||
| 19 | +qpdf: operation succeeded with warnings; resulting file may have some problems |
qpdf/qtest/qpdf/issue-143.pdf
0 → 100644
No preview for this file type