Commit 4b70fc3ce54310225cbbcf0ff6f4fac0f96d8fdd
1 parent
05469083
Enhance `QPDF_objects` to ignore excessively large object stream IDs in xref str…
…eams, improving robustness against damaged PDFs.
Showing
3 changed files
with
21 additions
and
3 deletions
libqpdf/QPDF_objects.cc
| @@ -1025,9 +1025,20 @@ QPDF::insertXrefEntry(int obj, int f0, qpdf_offset_t f1, int f2) | @@ -1025,9 +1025,20 @@ QPDF::insertXrefEntry(int obj, int f0, qpdf_offset_t f1, int f2) | ||
| 1025 | return; | 1025 | return; |
| 1026 | } | 1026 | } |
| 1027 | 1027 | ||
| 1028 | - if (f0 == 2 && static_cast<int>(f1) == obj) { | ||
| 1029 | - warn(damagedPDF("xref stream", "self-referential object stream " + std::to_string(obj))); | ||
| 1030 | - return; | 1028 | + if (f0 == 2) { |
| 1029 | + if (f1 == obj) { | ||
| 1030 | + warn( | ||
| 1031 | + damagedPDF("xref stream", "self-referential object stream " + std::to_string(obj))); | ||
| 1032 | + return; | ||
| 1033 | + } | ||
| 1034 | + if (f1 > m->xref_table_max_id) { | ||
| 1035 | + // ignore impossibly large object stream ids | ||
| 1036 | + warn(damagedPDF( | ||
| 1037 | + "xref stream", | ||
| 1038 | + "object stream id " + std::to_string(f1) + " for object " + std::to_string(obj) + | ||
| 1039 | + " is impossibly large")); | ||
| 1040 | + return; | ||
| 1041 | + } | ||
| 1031 | } | 1042 | } |
| 1032 | 1043 | ||
| 1033 | auto [iter, created] = m->xref_table.try_emplace(QPDFObjGen(obj, (f0 == 2 ? 0 : f2))); | 1044 | auto [iter, created] = m->xref_table.try_emplace(QPDFObjGen(obj, (f0 == 2 ? 0 : f2))); |
qpdf/qtest/qpdf/issue-118.out
| 1 | WARNING: issue-118.pdf: can't find PDF header | 1 | WARNING: issue-118.pdf: can't find PDF header |
| 2 | WARNING: issue-118.pdf (xref stream, offset 732): self-referential object stream 2 | 2 | WARNING: issue-118.pdf (xref stream, offset 732): self-referential object stream 2 |
| 3 | +WARNING: issue-118.pdf (xref stream, offset 732): object stream id 12336 for object 3 is impossibly large | ||
| 4 | +WARNING: issue-118.pdf (xref stream, offset 732): object stream id 12336 for object 4 is impossibly large | ||
| 5 | +WARNING: issue-118.pdf (xref stream, offset 732): object stream id 12336 for object 5 is impossibly large | ||
| 6 | +WARNING: issue-118.pdf (xref stream, offset 732): object stream id 12336 for object 6 is impossibly large | ||
| 3 | issue-118.pdf: unable to find /Root dictionary | 7 | issue-118.pdf: unable to find /Root dictionary |
qpdf/qtest/qpdf/issue-143.out
| @@ -4,6 +4,9 @@ WARNING: issue-143.pdf (xref stream: object 3 0, offset 607): stream dictionary | @@ -4,6 +4,9 @@ WARNING: issue-143.pdf (xref stream: object 3 0, offset 607): stream dictionary | ||
| 4 | WARNING: issue-143.pdf (xref stream: object 3 0, offset 654): attempting to recover stream length | 4 | WARNING: issue-143.pdf (xref stream: object 3 0, offset 654): attempting to recover stream length |
| 5 | WARNING: issue-143.pdf (xref stream: object 3 0, offset 654): recovered stream length: 36 | 5 | WARNING: issue-143.pdf (xref stream: object 3 0, offset 654): recovered stream length: 36 |
| 6 | WARNING: issue-143.pdf (xref stream, offset 654): self-referential object stream 3 | 6 | WARNING: issue-143.pdf (xref stream, offset 654): self-referential object stream 3 |
| 7 | +WARNING: issue-143.pdf (xref stream, offset 654): object stream id 12336 for object 4 is impossibly large | ||
| 8 | +WARNING: issue-143.pdf (xref stream, offset 654): object stream id 12336 for object 5 is impossibly large | ||
| 9 | +WARNING: issue-143.pdf (xref stream, offset 654): object stream id 12336 for object 6 is impossibly large | ||
| 7 | WARNING: issue-143.pdf: file is damaged | 10 | WARNING: issue-143.pdf: file is damaged |
| 8 | WARNING: issue-143.pdf (object 1 0, offset 48): expected n n obj | 11 | WARNING: issue-143.pdf (object 1 0, offset 48): expected n n obj |
| 9 | WARNING: issue-143.pdf: Attempting to reconstruct cross-reference table | 12 | WARNING: issue-143.pdf: Attempting to reconstruct cross-reference table |