Commit 8249a26d69f72b9cda584c14cc3f12769985e481

Authored by Jay Berkenbilt
1 parent 36b3fe5a

Fix infinite loop in QPDFWriter (fixes #143)

libqpdf/QPDFWriter.cc
... ... @@ -1054,6 +1054,9 @@ QPDFWriter::enqueueObject(QPDFObjectHandle object)
1054 1054 // here. Instead, enqueue the object stream. Object
1055 1055 // streams always have generation 0.
1056 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 1060 enqueueObject(this->pdf.getObjectByID(stream_id, 0));
1058 1061 }
1059 1062 else
... ... @@ -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 1092 else if (object.isArray())
1084 1093 {
... ...
qpdf/qpdf.testcov
... ... @@ -294,3 +294,4 @@ QPDF ignore first extra space in xref entry 0
294 294 QPDF ignore second extra space in xref entry 0
295 295 QPDF ignore length error xref entry 0
296 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 220 ["106", "zlib data error", 3],
221 221 ["141a", "/W entry size 0", 2],
222 222 ["141b", "/W entry size 0", 2],
  223 + ["143", "self-referential ostream", 3],
223 224 );
224 225 $n_tests += scalar(@bug_tests);
225 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