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

Index: PyPDF2-2.11.1/tests/test_filters.py
===================================================================
--- PyPDF2-2.11.1.orig/tests/test_filters.py
+++ PyPDF2-2.11.1/tests/test_filters.py
@@ -228,3 +228,9 @@ def test_issue_399():
     name = "tika-976970.pdf"
     reader = PdfReader(BytesIO(get_pdf_from_url(url, name=name)))
     reader.pages[1].extract_text()
+
+
+@pytest.mark.timeout(10)
+def test_asciihexdecode__speed():
+    encoded = (b"41" * 1_200_000) + b">"
+    ASCIIHexDecode.decode(encoded)
Index: PyPDF2-2.11.1/PyPDF2/filters.py
===================================================================
--- PyPDF2-2.11.1.orig/PyPDF2/filters.py
+++ PyPDF2-2.11.1/PyPDF2/filters.py
@@ -34,6 +34,7 @@ See TABLE H.1 Abbreviations for standard
 __author__ = "Mathieu Fenniak"
 __author_email__ = "biziqe@mathieu.fenniak.net"
 
+import binascii
 import math
 import struct
 import zlib
@@ -49,7 +50,7 @@ except ImportError:
     # For older Python versions, the backport typing_extensions is necessary:
     from typing_extensions import Literal  # type: ignore[misc]
 
-from ._utils import b_, deprecate_with_replacement, ord_, paeth_predictor
+from ._utils import b_, deprecate_with_replacement, ord_, paeth_predictor, logger_warning
 from .constants import CcittFaxDecodeParameters as CCITT
 from .constants import ColorSpaces
 from .constants import FilterTypeAbbreviations as FTA
@@ -242,25 +243,29 @@ class ASCIIHexDecode:
         if "decodeParms" in kwargs:  # pragma: no cover
             deprecate_with_replacement("decodeParms", "parameters", "4.0.0")
             decode_parms = kwargs["decodeParms"]  # noqa: F841
-        retval = ""
-        hex_pair = ""
-        index = 0
-        while True:
-            if index >= len(data):
-                raise PdfStreamError("Unexpected EOD in ASCIIHexDecode")
-            char = data[index]
-            if char == ">":
-                break
-            elif char.isspace():
-                index += 1
-                continue
-            hex_pair += char
-            if len(hex_pair) == 2:
-                retval += chr(int(hex_pair, base=16))
-                hex_pair = ""
-            index += 1
-        assert hex_pair == ""
-        return retval
+
+        if isinstance(data, str):
+            data = data.encode()
+
+        # Stop at EOD
+        eod = data.find(b">")
+        if eod == -1:
+            logger_warning(
+                "missing EOD in ASCIIHexDecode, check if output is OK",
+                __name__,
+            )
+            hex_data = data
+        else:
+            hex_data = data[:eod]
+
+        # Remove whitespace
+        hex_data = b"".join(hex_data.split())
+
+        # Pad if odd length
+        if len(hex_data) % 2 == 1:
+            hex_data += b"0"
+
+        return binascii.unhexlify(hex_data).decode()
 
 
 class LZWDecode:
openSUSE Build Service is sponsored by