File CVE-2026-27024.patch of Package python-PyPDF2

From bd2f6d052fe5941e85e37082c2a43453d48d1295 Mon Sep 17 00:00:00 2001
From: Stefan <96178532+stefan6419846@users.noreply.github.com>
Date: Tue, 17 Feb 2026 17:51:28 +0100
Subject: [PATCH] SEC: Detect cyclic references when accessing
 TreeObject.children (#3645)

---
 PyPDF2/generic/_data_structures.py     | 11 ++++++++++-
 tests/generic/test_data_structures.py | 18 ++++++++++++++++--
 2 files changed, 26 insertions(+), 3 deletions(-)

Index: PyPDF2-2.11.1/PyPDF2/generic/_data_structures.py
===================================================================
--- PyPDF2-2.11.1.orig/PyPDF2/generic/_data_structures.py
+++ PyPDF2-2.11.1/PyPDF2/generic/_data_structures.py
@@ -372,10 +372,19 @@ class TreeObject(DictionaryObject):
             return
 
         child_ref = self[NameObject("/First")]
+        last = self[NameObject("/Last")]
         child = child_ref.get_object()
+        visited: set[int] = set()
         while True:
+            child_id = id(child)
+            if child_id in visited:
+                logger_warning(f"Detected cycle in outline structure for {child}", __name__)
+                return
+            visited.add(child_id)
+
             yield child
-            if child == self[NameObject("/Last")]:
+
+            if child == last:
                 return
             child_ref = child.get(NameObject("/Next"))  # type: ignore
             if child_ref is None:
Index: PyPDF2-2.11.1/tests/test_generic.py
===================================================================
--- PyPDF2-2.11.1.orig/tests/test_generic.py
+++ PyPDF2-2.11.1/tests/test_generic.py
@@ -918,3 +918,17 @@ def test_create_string_object_force():
 )
 def test_float_object_decimal_to_string(value, expected):
     assert repr(FloatObject(value)) == expected
+
+
+def test_tree_object__cyclic_reference(caplog):
+    writer = PdfWriter()
+    child1 = writer._add_object(DictionaryObject())
+    child2 = writer._add_object(DictionaryObject({NameObject("/Next"): child1}))
+    child3 = writer._add_object(DictionaryObject({NameObject("/Next"): child2}))
+    child1.get_object()[NameObject("/Next")] = child3
+    tree = TreeObject()
+    tree[NameObject("/First")] = child2
+    tree[NameObject("/Last")] = writer._add_object(DictionaryObject())
+
+    assert list(tree.children()) == [child2.get_object(), child1.get_object(), child3.get_object()]
+    assert "Detected cycle in outline structure for " in caplog.text
openSUSE Build Service is sponsored by