Moderate severityNVD Advisory· Published Oct 22, 2025· Updated Oct 23, 2025
pypdf affected by possible infinite loop when reading DCT inline images without EOF marker
CVE-2025-62707
Description
pypdf is a free and open-source pure-python PDF library. Prior to version 6.1.3, an attacker who uses this vulnerability can craft a PDF which leads to an infinite loop. This requires parsing the content stream of a page which has an inline image using the DCTDecode filter. This has been fixed in pypdf version 6.1.3.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
pypdfPyPI | < 6.1.3 | 6.1.3 |
Affected products
1Patches
1f2864d6dd9baSEC: Avoid infinite loop when reading broken DCT-based inline images (#3501)
2 files changed · +31 −7
pypdf/generic/_image_inline.py+15 −7 modified@@ -148,18 +148,26 @@ def extract_inline_DCT(stream: StreamType) -> bytes: Extract DCT (JPEG) stream from inline image. The stream will be moved onto the EI. """ + def read(length: int) -> bytes: + # If 0 bytes are returned, and *size* was not 0, this indicates end of file. + # If the object is in non-blocking mode and no bytes are available, `None` is returned. + _result = stream.read(length) + if _result is None or len(_result) != length: + raise PdfReadError("Unexpected end of stream") + return _result + data_out: bytes = b"" # Read Blocks of data (ID/Size/data) up to ID=FF/D9 # https://www.digicamsoft.com/itu/itu-t81-36.html - notfirst = False + not_first = False while True: - c = stream.read(1) - if notfirst or (c == b"\xff"): + c = read(1) + if not_first or (c == b"\xff"): data_out += c if c != b"\xff": continue - notfirst = True - c = stream.read(1) + not_first = True + c = read(1) data_out += c if c == b"\xff": stream.seek(-1, 1) # pragma: no cover @@ -172,10 +180,10 @@ def extract_inline_DCT(stream: StreamType) -> bytes: b"\xda\xdb\xdc\xdd\xde\xdf" b"\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xfe" ): - c = stream.read(2) + c = read(2) data_out += c sz = c[0] * 256 + c[1] - data_out += stream.read(sz - 2) + data_out += read(sz - 2) ei_tok = read_non_whitespace(stream) ei_tok += stream.read(2)
tests/generic/test_image_inline.py+16 −0 modified@@ -1,7 +1,12 @@ """Test the pypdf.generic._image_inline module.""" from io import BytesIO +import pytest + +from pypdf import PdfReader +from pypdf.errors import PdfReadError from pypdf.generic._image_inline import is_followed_by_binary_data +from tests import get_data_from_url def test_is_followed_by_binary_data(): @@ -59,3 +64,14 @@ def test_is_followed_by_binary_data(): stream = BytesIO(b"1234.56 42 13 37 10 20 c\n") assert not is_followed_by_binary_data(stream) + + +@pytest.mark.enable_socket +def test_extract_inline_dct__early_end_of_file(): + url = "https://github.com/user-attachments/files/23056988/inline_dct__early_eof.pdf" + name = "inline_dct__early_eof.pdf" + reader = PdfReader(BytesIO(get_data_from_url(url, name=name))) + page = reader.pages[0] + + with pytest.raises(expected_exception=PdfReadError, match=r"^Unexpected end of stream$"): + page.images[0].image.load()
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
6- github.com/advisories/GHSA-vr63-x8vc-m265ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2025-62707ghsaADVISORY
- github.com/py-pdf/pypdf/commit/f2864d6dd9bac7cecd3f4f54308b25ebbfa178f8ghsax_refsource_MISCWEB
- github.com/py-pdf/pypdf/pull/3501ghsax_refsource_MISCWEB
- github.com/py-pdf/pypdf/releases/tag/6.1.3ghsax_refsource_MISCWEB
- github.com/py-pdf/pypdf/security/advisories/GHSA-vr63-x8vc-m265ghsax_refsource_CONFIRMWEB
News mentions
0No linked articles in our index yet.