Release note · August 6, 2026
A current signature boundary must bound the signature contents
A PDF signature’s /ByteRange usually leaves one gap for the signature value in /Contents. PDFFence 1.18 made a useful static question review-visible: does a semantic signature range reach the current physical file end? That endpoint still matters, but it is not the whole shape of the evidence. A two-pair range can reach EOF while its omitted span is not precisely the direct /Contents token at all.
PDFFence 1.19.0 adds a stricter, opt-in review gate for that narrower structural question. It does not turn a static inspection into signature validation.
The missing connection
Existing current-file evidence accepts an ordered, in-bounds /ByteRange that starts at byte zero and ends at the current EOF. That is intentionally a generic boundary classifier. It does not establish what its excluded gap represents.
The new aggregate evidence is positive only when all of these conditions hold for a semantic signature root:
- the range has exactly two pairs and reaches the current physical EOF;
- its single omitted span starts at the opening delimiter and ends after the closing delimiter of a direct hexadecimal
/Contentsstring; - that string is found in one xref-addressable, direct signature dictionary through a bounded raw lexical scan.
PDFFence still establishes a semantic signature only through a catalog-reachable AcroForm signature field, including inherited /FT, or catalog /Perms DocMDP, UR, or UR3. A private /PieceInfo dictionary that resembles /Type /Sig is not promoted into signature evidence.
PFP011: require a Contents-bound current range
The opt-in require_contents_bound_current_signature_coverage rule, PFP011, fails when an inspected PDF has semantic signature roots but no positive Contents-bound current-file count. Unsigned PDFs pass: this is not a demand that every PDF be signed.
version: 1
rules:
require_contents_bound_current_signature_coverage: true
This complements the two earlier gates. PFP009 asks whether current-file coverage fell across a comparison. PFP010 asks whether any current-file boundary exists now. PFP011 asks whether at least one of those current boundaries has its only omitted span exactly bound to direct /Contents.
A deliberately tight control
PDF Change Assurance Benchmark 1.19.0 adds a deterministic pair where both semantic ByteRanges remain well-formed and both reach EOF. In the candidate, the gap is widened by one byte before the direct /Contents token. The generic signature-coverage inventory changes and PFP011 fires; PFP009 and PFP010 correctly remain quiet.
The raw scan is intentionally conservative: by default it is capped at 1 MiB per candidate signature dictionary and 16 MiB per source file. An unavailable, indirect, malformed, or over-limit object does not earn positive evidence. This keeps the feature bounded and makes PFP011 a review gate that requires evidence, rather than a claim that all other PDFs are invalid.
Scope and validation
The PDF 2.0 signature errata explain the expected byte-range scope, while the PDF Association’s advisory shows why static structural checks cannot replace conforming validation. PFP011 does not calculate a digest, validate /Contents, certificates, trust chains, transforms, or permissions, and it does not decide whether an update is valid, permitted, safe, or malicious. Delimiter positions and signature bytes never appear in public output.
PDFFence passed 245 tests and Ruff; PDFCAB passed 86 tests and Ruff. The source candidates scored all 156 benchmark pairs through the public process boundary. Both packages built reproducibly with fixed timestamps and passed Twine metadata checks. Clean paired wheel installs on Python 3.12 and 3.13, plus a clean paired Python 3.12 source-archive install, passed dependency checks, fixture verification, and all 156 score cases.
The tagged policy reference, threat model, and validation record define the supported boundary.
python -m pip install https://github.com/SybilGambleyyu/pdffence/releases/download/v1.19.0/pdffence-1.19.0-py3-none-any.whl
pdffence check before.pdf after.pdf --policy pdffence.yml --format sarif
PDFFence is MIT-licensed and available on GitHub. The release assets include SHA-256 checksums for the wheel and source archive.