Skip to content

fix(deps): move PDF parsing to lopdf 0.42, clearing RUSTSEC-2026-0187 - #492

Merged
us merged 1 commit into
mainfrom
chore/deps-batch-2026-09
Sep 2, 2026
Merged

fix(deps): move PDF parsing to lopdf 0.42, clearing RUSTSEC-2026-0187#492
us merged 1 commit into
mainfrom
chore/deps-batch-2026-09

Conversation

@us

@us us commented Sep 2, 2026

Copy link
Copy Markdown
Owner

Lands four of the five open dependabot bumps as one change, because pdf-inspector
and lopdf have to move together.

Why now

.github/dependabot.yml carried a lopdf ignore waiting on exactly this:
pdf-inspector 1.17.0 is the first published release built on lopdf 0.42, which
carries the RUSTSEC-2026-0187 fix. lopdf 0.41 and earlier parse nested PDF arrays
with unbounded recursion, so a 21,095-byte file whose Catalog holds a 10,380-deep
array aborts the process with SIGABRT. A stack-overflow abort does not unwind, so
the catch_unwind in crw_extract::pdf::convert never covered it.

Same proof-of-concept file, both versions:

lopdf 0.41: fatal runtime error: stack overflow, aborting   exit 134
lopdf 0.42: OK loaded, 2 objects                            exit 0

Also exercised through the built binary against a local server serving that file:
the scrape returns cleanly instead of killing the process. deeply_nested_objects_do_not_abort
in crates/crw-extract/tests/pdf_tests.rs keeps it that way.

Why the 0.1.6 pin can come off

The pin was set because 0.1.7 gutted pages 6 to 11 of arXiv 1412.6980. Re-measured
over 29 real PDFs (ML papers, IRS forms and instructions, RFC 2616, a 10-K, the ECB
annual report, the UN SDG report, NIST CSF, the 756-page ISO PDF 32000-1 spec),
scoring word recall against pdftotext as ground truth:

0.1.6 1.17.0
weighted word recall (687,810 ground-truth words) 97.72% 98.15%
documents improved 23 of 29
worst regression -0.37 points
arXiv 1412.6980, per page 98.3-100% 97.2-100%

The raw character count falls 0.78%, which is not a loss: 1.17.0 rejoins hyphenated
line breaks and stops duplicating table rows. Both confirmed against poppler, e.g.
immediate parent of this one appears twice in the PDF spec, 0.1.6 emitted it four
times and 1.17.0 emits it twice. 1.17.0 also stops shredding small-caps runs, so the
Adam paper's title reads as a title instead of DAM : A M ETHOD FOR S TOCHASTIC.

Feature surface

pdf-inspector 1.15 added OCR through PDFium and ONNX Runtime, but default = []
still holds, so none of ocr, render-pdfium or model-download is enabled and no
native library enters the build. The only new non-optional dependency is
include_dir 0.7.

Contents

Not included: #472 (yaml-rust2 0.11 -> 0.12). The config crate pins 0.11 and it is
a dev-dependency used to parse docker-compose.yml in one test, so the bump only
adds a second yaml-rust2 and a second hashlink to the tree.

Deploy note

Merging this rebuilds the prod engine within the hour through the opencore.pin
bump, so the PDF path changes in production on merge, not at the next release.
No API shape, no config key and no default changes.

pdf-inspector 1.17.0 is the first published release built on lopdf 0.42, so the
workspace can finally follow. lopdf 0.41 and earlier parse nested PDF arrays
with unbounded recursion: a 21 KB file holding a 10,380-deep array in the
Catalog blows the stack and aborts the process with SIGABRT, which catch_unwind
cannot trap. Verified against a generated proof of concept, 0.41 aborts with
exit 134 and 0.42 loads it and returns. Bumping our own lopdf alongside keeps a
single copy in the tree.

The 0.1.6 pin was held because 0.1.7 gutted pages 6 to 11 of arXiv 1412.6980.
Re-measured over 29 real PDFs (papers, IRS forms, RFC 2616, a 10-K, the
756-page PDF spec) scoring word recall against poppler as ground truth: 1.17.0
reaches 98.15% against 0.1.6's 97.72%, better on 23 of the 29 documents, and
every page of 1412.6980 comes back at 97 to 100%. The raw character count falls
0.78% only because 1.17.0 rejoins hyphenated line breaks and stops duplicating
table rows, both confirmed against poppler.

OCR stays out of the build: pdf-inspector's default feature set is still empty,
so PDFium and ONNX Runtime are not pulled in.

- pdf-inspector 0.1.6 -> 1.17.0, lopdf 0.41 -> 0.42
- base64 0.22 -> 0.23, jsonschema 0.50.0 -> 0.50.1
- drop the lopdf and pdf-inspector 0.1.7 dependabot ignores, both now moot
- regression test for the nested-object abort
@us
us merged commit 10f4341 into main Sep 2, 2026
12 checks passed
@github-actions github-actions Bot locked and limited conversation to collaborators Sep 2, 2026
@us
us deleted the chore/deps-batch-2026-09 branch September 2, 2026 01:41
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant