From 4b70fc3ce54310225cbbcf0ff6f4fac0f96d8fdd Mon Sep 17 00:00:00 2001 From: m-holger Date: Thu, 31 Jul 2025 18:11:47 +0100 Subject: [PATCH] Enhance `QPDF_objects` to ignore excessively large object stream IDs in xref streams, improving robustness against damaged PDFs. --- libqpdf/QPDF_objects.cc | 17 ++++++++++++++--- qpdf/qtest/qpdf/issue-118.out | 4 ++++ qpdf/qtest/qpdf/issue-143.out | 3 +++ 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/libqpdf/QPDF_objects.cc b/libqpdf/QPDF_objects.cc index b2a352d..ecae23d 100644 --- a/libqpdf/QPDF_objects.cc +++ b/libqpdf/QPDF_objects.cc @@ -1025,9 +1025,20 @@ QPDF::insertXrefEntry(int obj, int f0, qpdf_offset_t f1, int f2) return; } - if (f0 == 2 && static_cast(f1) == obj) { - warn(damagedPDF("xref stream", "self-referential object stream " + std::to_string(obj))); - return; + if (f0 == 2) { + if (f1 == obj) { + warn( + damagedPDF("xref stream", "self-referential object stream " + std::to_string(obj))); + return; + } + if (f1 > m->xref_table_max_id) { + // ignore impossibly large object stream ids + warn(damagedPDF( + "xref stream", + "object stream id " + std::to_string(f1) + " for object " + std::to_string(obj) + + " is impossibly large")); + return; + } } auto [iter, created] = m->xref_table.try_emplace(QPDFObjGen(obj, (f0 == 2 ? 0 : f2))); diff --git a/qpdf/qtest/qpdf/issue-118.out b/qpdf/qtest/qpdf/issue-118.out index 2b219b2..1dc9df1 100644 --- a/qpdf/qtest/qpdf/issue-118.out +++ b/qpdf/qtest/qpdf/issue-118.out @@ -1,3 +1,7 @@ WARNING: issue-118.pdf: can't find PDF header WARNING: issue-118.pdf (xref stream, offset 732): self-referential object stream 2 +WARNING: issue-118.pdf (xref stream, offset 732): object stream id 12336 for object 3 is impossibly large +WARNING: issue-118.pdf (xref stream, offset 732): object stream id 12336 for object 4 is impossibly large +WARNING: issue-118.pdf (xref stream, offset 732): object stream id 12336 for object 5 is impossibly large +WARNING: issue-118.pdf (xref stream, offset 732): object stream id 12336 for object 6 is impossibly large issue-118.pdf: unable to find /Root dictionary diff --git a/qpdf/qtest/qpdf/issue-143.out b/qpdf/qtest/qpdf/issue-143.out index 40a721c..d9a5275 100644 --- a/qpdf/qtest/qpdf/issue-143.out +++ b/qpdf/qtest/qpdf/issue-143.out @@ -4,6 +4,9 @@ WARNING: issue-143.pdf (xref stream: object 3 0, offset 607): stream dictionary WARNING: issue-143.pdf (xref stream: object 3 0, offset 654): attempting to recover stream length WARNING: issue-143.pdf (xref stream: object 3 0, offset 654): recovered stream length: 36 WARNING: issue-143.pdf (xref stream, offset 654): self-referential object stream 3 +WARNING: issue-143.pdf (xref stream, offset 654): object stream id 12336 for object 4 is impossibly large +WARNING: issue-143.pdf (xref stream, offset 654): object stream id 12336 for object 5 is impossibly large +WARNING: issue-143.pdf (xref stream, offset 654): object stream id 12336 for object 6 is impossibly large WARNING: issue-143.pdf: file is damaged WARNING: issue-143.pdf (object 1 0, offset 48): expected n n obj WARNING: issue-143.pdf: Attempting to reconstruct cross-reference table -- libgit2 0.21.4