Bump pypdf from 6.11.0 to 6.21.2

SU
2d ago
+3-3

Updates pypdf from 6.11.0 to 6.21.2.

Fixes GHSA-6c7f-9265-g8fw and CVE-2026-115572 — a small PDF holds an API worker for over a minute: a 1,180,298-byte upload to the unauthenticated /general/v0/general route costs 69.9 s in the page-tree walk while the same bytes cost 0.025 s on the fixed release, and the route sets no request timeout and no upload size cap, so a few concurrent uploads deny service.

What this changes:

  • uv.lock — pypdf moves from 6.11.0 to 6.21.2, with the sdist and wheel entries that release publishes; no other package or line changes

How to verify:

uv lock --check
uv sync --locked --no-dev --no-install-project && .venv/bin/python -c "import pypdf; print(pypdf.__version__)"
python3 -c "import pypdf; pypdf.PdfReader('poc_20k_1m.pdf').pages" # 69.92 s on 6.11.0, 0.025 s on 6.21.2

Why the API route is exposed

POST /general/v0/general (prepline_general/api/general.py:646-647) -> general_partition -> _check_pdf(file) at general.py:308 -> PdfReader(file) at general.py:494 -> list(pdf.pages) at general.py:503; the route needs no credentials and sets no request timeout.
Dockerfile:63-64 copies uv.lock and runs uv sync --no-dev --no-install-project --locked, so the API image runs exactly the pypdf version the lock pins, which is 6.11.0.
In 6.11.0 a missing object is cached as None but the cache lookup returns early only for a non-None hit (pypdf/_reader.py:447-451), so each of the 20,000 references re-copies and re-scans the whole stream (:558-570). 6.21.2 adds the resolved-objects membership test (_reader.py:552-557, PR #4240) and stops after the first miss.

Measured on one 1.2 MB PDF, same bytes both sides

runpypdf 6.11.0pypdf 6.21.2
PdfReader(...).pages, median of 369.92 s0.025 s
POST /general/v0/general on loopback171.32 s (HTTP 200, body [])1.27 s (HTTP 200, body [])
same-size benign 1.2 MB PDF0.0006 s (library) / 0.219 s (served)0.185 s (served)
Payload: 1,180,298 B, sha256 97d67e8d9d6eb9786cf6f7fcb08dcb05fc3cc31ace61c65780f812ef3236e132; its /Kids array names object 9999 20,000 times and object 9999 is never defined, so every reference is a cache miss.

The patched lock was re-checked and installed with the repository's own uv 0.13.4 and its own build step before submission, and both pinned releases were re-run on the payload on this host.

Automated security patch from Superbot.