VYPR
Low severityNVD Advisory· Published Feb 25, 2026· Updated Feb 27, 2026

pypdf has a possible infinite loop when loading circular /Prev entries in cross-reference streams

CVE-2026-27628

Description

pypdf is a free and open-source pure-python PDF library. Prior to 6.7.2, an attacker who uses this vulnerability can craft a PDF which leads to an infinite loop. This requires reading the file. This has been fixed in pypdf 6.7.2. As a workaround, one may apply the patch manually.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
pypdfPyPI
< 6.7.26.7.2

Affected products

1

Patches

1
f0a462d36971

SEC: Prevent infinite loop from circular xref /Prev references (#3655)

https://github.com/py-pdf/pypdfJose Angel TorresFeb 22, 2026via ghsa
2 files changed · +45 0
  • pypdf/_reader.py+9 0 modified
    @@ -871,7 +871,16 @@ def _read_xref_tables_and_trailers(
             self.xref_free_entry = {}
             self.xref_objStm = {}
             self.trailer = DictionaryObject()
    +        visited_xref_offsets: set[int] = set()
             while startxref is not None:
    +            # Detect circular /Prev references in the xref chain
    +            if startxref in visited_xref_offsets:
    +                logger_warning(
    +                    f"Circular xref chain detected at offset {startxref}, stopping",
    +                    __name__,
    +                )
    +                break
    +            visited_xref_offsets.add(startxref)
                 # load the xref table
                 stream.seek(startxref, 0)
                 x = stream.read(1)
    
  • tests/test_reader.py+36 0 modified
    @@ -562,6 +562,42 @@ def test_read_prev_0_trailer():
         assert exc.value.args[0] == "/Prev=0 in the trailer (try opening with strict=False)"
     
     
    +def test_circular_xref_prev_reference(caplog):
    +    """Circular /Prev in trailer should be detected, not loop forever (#3654)."""
    +    pdf_data = (
    +        b"%%PDF-1.7\n"
    +        b"1 0 obj << /Count 1 /Kids [4 0 R] /Type /Pages >> endobj\n"
    +        b"2 0 obj << >> endobj\n"
    +        b"3 0 obj << >> endobj\n"
    +        b"4 0 obj << /Contents 3 0 R /CropBox [0.0 0.0 2550.0 3508.0]"
    +        b" /MediaBox [0.0 0.0 2550.0 3508.0] /Parent 1 0 R"
    +        b" /Resources << /Font << >> >>"
    +        b" /Rotate 0 /Type /Page >> endobj\n"
    +        b"5 0 obj << /Pages 1 0 R /Type /Catalog >> endobj\n"
    +        b"xref 1 5\n"
    +        b"%010d 00000 n\n"
    +        b"%010d 00000 n\n"
    +        b"%010d 00000 n\n"
    +        b"%010d 00000 n\n"
    +        b"%010d 00000 n\n"
    +        b"trailer << /Prev %d /Root 5 0 R /Size 6 >>\n"
    +        b"startxref %d\n"
    +        b"%%%%EOF"
    +    )
    +    xref_offset = pdf_data.find(b"xref") - 1
    +    pdf_data = pdf_data % (
    +        pdf_data.find(b"1 0 obj"),
    +        pdf_data.find(b"2 0 obj"),
    +        pdf_data.find(b"3 0 obj"),
    +        pdf_data.find(b"4 0 obj"),
    +        pdf_data.find(b"5 0 obj"),
    +        xref_offset,  # /Prev points to same xref = circular
    +        xref_offset,  # startxref
    +    )
    +    PdfReader(io.BytesIO(pdf_data))
    +    assert "Circular xref chain detected" in caplog.text
    +
    +
     def test_read_missing_startxref():
         pdf_data = (
             b"%%PDF-1.7\n"
    

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

5

News mentions

0

No linked articles in our index yet.