Skip to content

Commit 3bf614e

Browse files
authored
Raise an error if the trailer chain loops back on itself (#9519)
1 parent 3cb854e commit 3bf614e

File tree

3 files changed

+13
-2
lines changed

3 files changed

+13
-2
lines changed

Tests/images/trailer_loop.pdf

1.78 KB
Binary file not shown.

Tests/test_pdfparser.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,3 +125,8 @@ def test_duplicate_xref_entry() -> None:
125125
pdf = PdfParser("Tests/images/duplicate_xref_entry.pdf")
126126
assert pdf.xref_table.existing_entries[6][0] == 1197
127127
pdf.close()
128+
129+
130+
def test_trailer_loop() -> None:
131+
with pytest.raises(PdfFormatError, match="trailer loop found"):
132+
PdfParser("Tests/images/trailer_loop.pdf")

src/PIL/PdfParser.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -685,7 +685,9 @@ def read_trailer(self) -> None:
685685
if b"Prev" in self.trailer_dict:
686686
self.read_prev_trailer(self.trailer_dict[b"Prev"])
687687

688-
def read_prev_trailer(self, xref_section_offset: int) -> None:
688+
def read_prev_trailer(
689+
self, xref_section_offset: int, processed_offsets: list[int] = []
690+
) -> None:
689691
assert self.buf is not None
690692
trailer_offset = self.read_xref_table(xref_section_offset=xref_section_offset)
691693
m = self.re_trailer_prev.search(
@@ -700,7 +702,11 @@ def read_prev_trailer(self, xref_section_offset: int) -> None:
700702
)
701703
trailer_dict = self.interpret_trailer(trailer_data)
702704
if b"Prev" in trailer_dict:
703-
self.read_prev_trailer(trailer_dict[b"Prev"])
705+
processed_offsets.append(xref_section_offset)
706+
check_format_condition(
707+
trailer_dict[b"Prev"] not in processed_offsets, "trailer loop found"
708+
)
709+
self.read_prev_trailer(trailer_dict[b"Prev"], processed_offsets)
704710

705711
re_whitespace_optional = re.compile(whitespace_optional)
706712
re_name = re.compile(

0 commit comments

Comments
 (0)