Skip to content

Commit 432b238

Browse files
ROB: Raise proper error on infinite loop when reading objects (#3169)
Closes #3112.
1 parent c4c6dea commit 432b238

File tree

2 files changed

+20
-0
lines changed

2 files changed

+20
-0
lines changed

pypdf/_reader.py

+8
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
Iterable,
4141
List,
4242
Optional,
43+
Set,
4344
Tuple,
4445
Type,
4546
Union,
@@ -133,6 +134,7 @@ def __init__(
133134
self._validated_root: Optional[DictionaryObject] = None
134135

135136
self._initialize_stream(stream)
137+
self._known_objects: Set[Tuple[int, int]] = set()
136138

137139
self._override_encryption = False
138140
self._encryption: Optional[Encryption] = None
@@ -447,7 +449,13 @@ def get_object(
447449
)
448450
if self.strict:
449451
assert generation == indirect_reference.generation
452+
453+
current_object = (indirect_reference.idnum, indirect_reference.generation)
454+
if current_object in self._known_objects:
455+
raise PdfReadError(f"Detected loop with self reference for {indirect_reference!r}.")
456+
self._known_objects.add(current_object)
450457
retval = read_object(self.stream, self) # type: ignore
458+
self._known_objects.remove(current_object)
451459

452460
# override encryption is used for the /Encrypt dictionary
453461
if not self._override_encryption and self._encryption is not None:

tests/test_reader.py

+12
Original file line numberDiff line numberDiff line change
@@ -1806,3 +1806,15 @@ def test_issue2886(caplog):
18061806

18071807
with pytest.raises(PdfReadError, match="Unexpected empty line in Xref table."):
18081808
_ = PdfReader(BytesIO(get_data_from_url(url, name=name)))
1809+
1810+
1811+
@pytest.mark.enable_socket
1812+
def test_infinite_loop_for_length_value():
1813+
"""Tests for #3112"""
1814+
url = "https://github.com/user-attachments/files/19106009/Special.n.15.du.jeudi.22.fevrier.2024.pdf"
1815+
name = "issue3112.pdf"
1816+
1817+
reader = PdfReader(BytesIO(get_data_from_url(url, name=name)))
1818+
writer = PdfWriter()
1819+
with pytest.raises(PdfReadError, match=r"^Detected loop with self reference for IndirectObject\(165, 0, \d+\)\.$"):
1820+
writer.add_page(reader.pages[0])

0 commit comments

Comments
 (0)