Commit 4b70fc3ce54310225cbbcf0ff6f4fac0f96d8fdd

Authored by m-holger
1 parent 05469083

Enhance `QPDF_objects` to ignore excessively large object stream IDs in xref str…

…eams, improving robustness against damaged PDFs.
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