Commit Graph
107 Commits
Author SHA1 Message Date
Dylan M. Taylor 87aebd1b24 fix(preflight): follow every /Next action and bound colour and intent work (#5926)
* fix(preflight): follow every /Next action and bound colour and intent work

Action chains followed an indirect /Next only when it named an array, and
skipped references inside a /Next array, so a forbidden action one indirect
hop behind an allowed one survived both verification and conversion; an
untyped dictionary with /P and /K was exempt from action checks whatever its
/S. Both are now followed and checked, and arrays are borrowed instead of
deep-copied per chain. Conversion treats a /Subtype /Widget without /Type as
an annotation, and takes forbidden annotations off their pages in one pass.

Device-colour inspection decoded each content stream with the 1 GiB
per-stream default and no total; it now shares one 1 GiB DecodeBudget and
reports unread content instead of treating it as clean. Type 3 CharProcs
shared by many fonts are read once, and declared() reads each output intent
once (at most 8).

* address review: no sRGB intent when colour couldn't all be read; count array reads in action chains; declare every output intent

* address review: cut only an over-long identifier; test with a filter that can't be read

* review: leave untyped structure elements out of the forbidden-action check

* merge main, keep both

* address review: a wide direct /Next array is refused before it is queued; queued references are resolved through aliases
2026-11-11 14:47:29 -05:00
FredApps 235ede4896 Print: flatten transparent sheets for GDI (v3) printer drivers (#6155, #5838, #5940) (#6955)
* Print: flatten transparent sheets for GDI (v3) printer drivers

Windows sends a job for a GDI (v3) driver through its XPS-to-GDI
conversion, which fails on soft masks (#6155), prints halos around them
(#5838) or prints transparency as black boxes (#5940). XPS (v4) drivers
print the same pages correctly.

spooler_copy takes a flatten_transparency flag. With it, after greying
and before tiling, each sheet that uses transparency is replaced by an
opaque picture of itself (spooler::flattened): rendered at 300 dpi, lower
for a sheet past 80 MP or 16000 px a side, in tiles of at most
2000 x 2000 px, each an RGB Flate image over white, so no tile reaches
Windows' 2^22 px image cap and tiling leaves them alone. The sheet keeps
its boxes and rotation; its group and annotations go. Sheets without
transparency stay vector.

pdfcraft-preflight gets page_uses_transparency, the PDF/A transparency
search without counting a transparency group on its own, which Word
puts on every page.

Both callers pass false until the GDI-driver check lands.

* Print: flatten transparent sheets only for a GDI (v3) printer driver

spool::xps_driver / spool::gdi_driver read whether the printer's driver renders XPS itself,
through craft-print's new xps_driver (storytold/craft-libs#804, winprint
storytold/winprint.rs#21). The Print dialog and doc_print pass gdi_driver to spooler_copy's
flatten_transparency, so XPS (v4) drivers, PDF printers among them, keep vector sheets.

craft-print pinned to the craft-libs#804 branch, winprint to #21's, until they merge.

* craft-print 60ede99985ef1e5df87a2aca66ed538eb23dec99: craft-libs main with #804 (xps_driver), winprint bc06a7c4 (#21)

* Cargo.lock: the two winprint entries in Cargo's order (by source, after the re-pin)
2026-11-11 08:41:07 +01:00
jonathanwxh-cell 9ccd6964ee fix(preflight): handle typeless annotations, indexed colour, and indirect filters (#5279) 2026-11-10 09:59:28 +07:00
jonathanwxh-cell 47961c2077 fix(preflight): walk soft-mask groups, indirect subtypes, and type 5 halftones (#6680) 2026-11-09 18:04:26 +08:00
jonathanwxh-cell 4d2aa29ee7 fix(preflight): resolve indirect spot families, null dict entries, and numeric equality (#6679) 2026-11-09 18:04:02 +08:00
bflatastic 4e86cd337d Give the preflight test fixtures a PDF/A-2 file header
The header check reports a file without the binary comment, and Save as PDF/A then makes the next save a full one. The known-answer documents and the generation-repair file predate it: the minimal document got a 6.1.2 issue, and an undamaged file needed a full save for its header instead of being saved incrementally. They now start with the comment, as the crate's unit test documents do.
2026-11-09 09:56:47 +07:00
bflatastic d9f55b0a69 Split PDF/A verify into one helper per group of clause checks
verify() went past clippy's cognitive complexity limit once every check was in it. The checks move as they are into helpers, run in the same order, so the issues and their order don't change.
2026-11-09 09:03:01 +07:00
bflatastic cea263ddbf Merge #6219: M11: PDF/A verify reports pages with transparency but no blending colour space, and blend modes ISO 32000-1 doesn't define (optimize.pdfa-validate)
# Conflicts:
#	crates/preflight/src/lib.rs
#	crates/preflight/src/tests.rs
#	parity/acrobat-features.toml
2026-11-09 08:12:33 +07:00
bflatastic b3a5ac3ac1 Merge #6215: M11: PDF/A verify reports SetState, NOP and Named actions other than the four page moves (optimize.pdfa-validate)
# Conflicts:
#	crates/preflight/src/tests.rs
#	parity/acrobat-features.toml
2026-11-09 08:11:26 +07:00
bflatastic 6be3850177 Merge #6214: M11: PDF/A verify checks the file identifier and Save as PDF/A adds one (optimize.pdfa-validate)
# Conflicts:
#	crates/automation/src/tools.rs
#	crates/cos/src/lib.rs
#	crates/preflight/src/lib.rs
#	crates/preflight/src/tests.rs
#	parity/acrobat-features.toml
2026-11-09 08:10:01 +07:00
bflatastic 174d0b31e8 Merge #6207: M11: PDF/A verify reports transfer functions, halftones and rendering intents a graphics state may not use (optimize.pdfa-validate)
# Conflicts:
#	crates/preflight/src/lib.rs
#	crates/preflight/src/tests.rs
#	parity/acrobat-features.toml
2026-11-09 08:08:08 +07:00
bflatastic e2417e1561 Merge #6206: M11: PDF/A verify checks the file header and Save as PDF/A rewrites it (optimize.pdfa-validate)
# Conflicts:
#	crates/preflight/src/tests.rs
#	parity/acrobat-features.toml
2026-11-09 08:07:05 +07:00
bflatastic fd204ced66 Merge #6203: M11: PDF/A verify reports Separation spaces of one name that differ and DeviceN spot colours missing from /Colorants (optimize.pdfa-validate)
# Conflicts:
#	crates/preflight/src/lib.rs
#	crates/preflight/src/tests.rs
#	parity/acrobat-features.toml
2026-11-09 08:05:52 +07:00
bflatastic 25ac77c360 Merge #6202: M11: PDF/A verify reports integers, reals, strings, names, CIDs and page boundaries past the implementation limits (optimize.pdfa-validate)
# Conflicts:
#	crates/preflight/src/lib.rs
#	parity/acrobat-features.toml
2026-11-09 08:04:54 +07:00
bflatastic 4f90d2295f Merge #6172: M11: PDF/A verify asks only the fonts something draws with to be embedded (optimize.pdfa-validate)
# Conflicts:
#	crates/preflight/src/tests.rs
2026-11-09 08:03:56 +07:00
mtlcl410andClaude Opus 5.5 3fe8ee4774 M11: PDF/A verify checks SetState, NOP and Named actions in open actions, standalone actions and links (6.5.1)
The test now places each of them in the catalog's /OpenAction (direct and
by reference), in an action of its own that a page's /AA refers to, and in
a link's /A, and adds a Named action whose /N refers to /Print. Save as
PDF/A removes each and keeps a Named page move.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pq7HyCHD1R3rywQBPCHXZA
2026-11-09 08:54:03 +08:00
mtlcl410 4f97a22a2e Merge remote-tracking branch 'upstream/main' into lane6-6215
# Conflicts:
#	crates/preflight/src/tests.rs
#	parity/acrobat-features.toml
2026-11-09 08:54:02 +08:00
mtlcl410andClaude Opus 5.5 2b0fdedffb Merge upstream/main into fix/pdfa-implementation-limits
Resolve conflicts with the XMP value-type checks (6.6.2.3.1): keep both
sets of tests, and combine the pdfa-verify parity evidence and notes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pq7HyCHD1R3rywQBPCHXZA
2026-11-09 08:52:16 +08:00
mtlcl410andClaude Opus 5.5 8c2ef13de6 Merge upstream/main into fix/pdfa-separation-devicen
Resolve conflicts with the XMP value-type checks (6.6.2.3.1): keep both
sets of tests, and combine the pdfa-verify parity evidence and notes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pq7HyCHD1R3rywQBPCHXZA
2026-11-09 08:50:28 +08:00
mtlcl410 ee2398f710 M11: PDF/A verify checks that predefined XMP properties have their value types (optimize.pdfa-validate) (#6220) 2026-11-09 08:37:56 +08:00
mtlcl410andClaude Opus 5.5 f89efbcf19 Merge branch 'fix/pdfa-xmp-exif-types' into fix/pdfa-xmp-extension-schemas
Brings in #6220's written-name wording for 6.6.2.3.1 alongside the
extension schema findings; the duplicated type-name test keeps the
version that covers both the base and the EXIF types.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pq7HyDBXygTf7jcqdsjcfn
2026-11-07 08:35:33 +08:00
mtlcl410 19f4e1ef21 Merge branch 'fix/pdfa-xmp-value-types' into fix/pdfa-xmp-exif-types
# Conflicts:
#	crates/preflight/src/lib.rs
#	crates/preflight/src/tests.rs
#	crates/preflight/src/xmp_types.rs
#	parity/acrobat-features.toml
2026-11-07 08:33:30 +08:00
mtlcl410andClaude Opus 5.5 e6b5f2120c M11: PDF/A verify says where a mistyped XMP property is, as written, and its type (6.6.2.3.1)
A 6.6.2.3.1 issue now names the metadata stream that holds the property
and carries its ObjRef in Issue::object, so a property mistyped in two
streams is two issues. Wordings that name several things use named holes,
filled in one pass. The message names the value type the XMP
Specification gives the property (Integer, Lang Alt, seq ResourceEvent,
Dimensions), and, when the packet writes the property with another prefix
than the preferred one or none, the name as written.

Tests also show that a property is known by its namespace URI, and that a
property a predefined namespace doesn't define, or a namespace that isn't
predefined, is left alone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pq7HyDBXygTf7jcqdsjcfn
2026-11-07 08:32:05 +08:00
mtlcl410andClaude Opus 5.5 916bca01c8 M11: 6.2.10 names the page of an unknown blend mode and reads shared resources once
The unknown-blend-mode issue carries its page, as the transparency issue
does. Pages keep what was found under the indirect objects they share
(resources, forms, patterns, Type 3 fonts, graphics states) in a
document-wide map, filled only from objects read to the end, so the next
page takes them in one read. The walk reads objects in place instead of
copying resources dictionaries and their entries, and gathers at most 32
unknown blend mode names.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pq7HyDBXygTf7jcqdsjcfn
2026-11-07 08:28:41 +08:00
mtlcl410 ea59d8c69a Merge remote-tracking branch 'upstream/main' into fix/pdfa-xmp-value-types 2026-11-07 08:27:24 +08:00
mtlcl410andClaude Opus 5.5 8ca675b25d M11: PDF/A verify finds empty naming entries in XMP extension schema descriptions (6.6.2.3.3)
A namespace URI, prefix, name, value type, type or category entry that is
there but empty names nothing; it is now reported with its own wording.
Descriptions stay free to be empty Text.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pq7HyDBXygTf7jcqdsjcfn
2026-11-07 08:26:45 +08:00
mtlcl410 ac30985c96 Merge remote-tracking branch 'upstream/main' into fix/pdfa-transparency-group 2026-11-07 08:21:11 +08:00
mtlcl410andClaude Opus 5.5 1820ba241e M11: PDF/A verify says where each XMP extension schema finding is (optimize.pdfa-validate)
6.6.2.3.3 findings are now reported per description instead of once per
entry name: each names the schema by its pdfaSchema:namespaceURI (or #n),
the property, value type or field by its own name (a field as type/name),
and the metadata stream, with Issue::object set. A misused prefix names
the namespace URI and the prefix written (or that none was); a container
that isn't one rdf:Bag names what it holds instead. Findings are capped at
1000 per document and repeated names at 200 characters.

6.6.2.3.1 issues now name the type the XMP Specification gives the
property, as the specification writes it (Integer, seq Rational,
Lang Alt, Flash); structure types carry their names for this.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-07 06:53:21 +08:00
mtlcl410 00f24531dd Merge branch 'fix/pdfa-xmp-exif-types' into fix/pdfa-xmp-extension-schemas
# Conflicts:
#	crates/preflight/src/lib.rs
#	crates/preflight/src/tests.rs
#	crates/preflight/src/xmp_types.rs
#	parity/acrobat-features.toml
2026-11-07 06:46:52 +08:00
mtlcl410 23ed9c6df9 Merge remote-tracking branch 'upstream/main' into fix/pdfa-xmp-extension-schemas 2026-11-07 06:46:13 +08:00
mtlcl410andClaude Opus 5.5 173cfa5390 M11: PDF/A verify names the metadata stream of a mistyped XMP property (optimize.pdfa-validate)
A 6.6.2.3.1 issue now says which metadata stream holds the property
("in metadata stream 5 0 R") and carries its ObjRef in Issue::object, so a
property mistyped in more than one stream is reported once per stream.
Wordings that name more than one thing use named holes, such as {object},
filled in one pass with the {} value, so a translation can reorder them.

Tests: the stream is named and located per issue; a non-preferred prefix
bound to the TIFF, EXIF or aux namespace URI is checked, and the preferred
prefixes bound to other URIs are not, proving the lookup is by URI.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-07 06:46:03 +08:00
mtlcl410 8bbe2cdd46 Merge remote-tracking branch 'upstream/main' into fix/pdfa-xmp-exif-types 2026-11-07 06:37:28 +08:00
mtlcl410 ea54453ad2 Merge remote-tracking branch 'upstream/main' into pr-6214
# Conflicts:
#	crates/cos/src/lib.rs
2026-11-06 19:11:57 +08:00
eliets2andeliets2 bb9da1c1c2 Convert replaces a removed forbidden annotation, so it is not reported again (#6306)
Co-authored-by: eliets2 <287273517+eliets2@users.noreply.github.com>
2026-11-05 20:32:39 +01:00
eliets2andeliets2 9a95273c7c Fuzz targets for PDF/A verify and convert (#6308)
Co-authored-by: eliets2 <287273517+eliets2@users.noreply.github.com>
2026-11-05 20:11:27 +01:00
eliets2andeliets2 b1c1dbdad3 One known-answer case per implemented clause (#6301)
Co-authored-by: eliets2 <287273517+eliets2@users.noreply.github.com>
2026-11-05 20:11:00 +01:00
mtlcl410 96e8a34346 Merge branch 'fix/pdfa-xmp-exif-types' into fix/pdfa-xmp-extension-schemas 2026-11-05 17:27:55 +08:00
mtlcl410 8984b2516e Merge branch 'fix/pdfa-xmp-value-types' into fix/pdfa-xmp-exif-types 2026-11-05 17:26:35 +08:00
mtlcl410andClaude Opus 5.5 7dad9e784a M11: PDF/A verify takes an rdf:value attribute in place of the element, not beside it (6.6.2.3.1)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pq7HyDBXygTf7jcqdsjcfn
2026-11-05 17:21:39 +08:00
mtlcl410andClaude Opus 5.5 97d054e14f M11: tests: the second extension property list is the incomplete one (6.6.2.3.3)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pq7HyDBXygTf7jcqdsjcfn
2026-11-05 17:05:05 +08:00
mtlcl410andClaude Opus 5.5 5241619b96 M11: PDF/A verify reads every repeated extension schema list and wants a Bag container (6.6.2.3.3)
A schema's property or value type list, or a value type's field list,
written more than once is read each time; and a pdfaExtension:schemas
that isn't one rdf:Bag (TechNote 0009, 4.2) is reported.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pq7HyDBXygTf7jcqdsjcfn
2026-11-05 17:04:40 +08:00
mtlcl410 cf23f7607d Merge branch 'fix/pdfa-xmp-exif-types' into fix/pdfa-xmp-extension-schemas
# Conflicts:
#	crates/preflight/src/tests.rs
2026-11-05 17:03:51 +08:00
mtlcl410 b8e0f16255 Merge branch 'fix/pdfa-xmp-value-types' into fix/pdfa-xmp-exif-types
# Conflicts:
#	crates/preflight/src/tests.rs
2026-11-05 17:02:08 +08:00
mtlcl410andClaude Opus 5.5 abf0f94e78 M11: PDF/A verify allows only XMP's value forms: one rdf:value, parseType Resource, empty rdf:resource (6.6.2.3.1)
A qualified value has exactly one rdf:value; a parse type other than
Resource, which XMP doesn't use (ISO 16684-1 7.9.2.5), breaks the value;
and an rdf:resource element holds no element content in any form.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pq7HyDBXygTf7jcqdsjcfn
2026-11-05 16:56:37 +08:00
mtlcl410andClaude Opus 5.5 7afa1e8b24 M11: PDF/A verify requires the pdfaExtension prefix too, citing TechNote 0009 (6.6.2.3.3)
All five extension schema container namespaces are written with their
own prefixes, pdfaExtension included (PDF Association TechNote 0009,
4.1). The module comment cites TechNote 0009 section 4 for the schemas,
entries and prefixes, and says where PDF/A-2 asks more than it does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pq7HyDBXygTf7jcqdsjcfn
2026-11-05 16:29:20 +08:00
863af864a7 M1: respect generations in PDF object references and full saves (#1143)
* M1: respect generations in COS object references and full saves

Resolve stale references to null instead of replacement objects with the
same number. Validate complete identities in writer readers, indirect
stream lengths and catalog checks, and keep generation-aware length caches.

Cover cache reuse, edit overlays, snapshots, incremental and packed/classic
full saves, and stream lengths with synthetic regressions and independent
hayro checks.

Co-Authored-By: Codex <noreply@openai.com>

* M0: clarify refreshed CI roadmap note

Co-authored-by: OpenAI Codex <noreply@openai.com>

* M1: repair contradictory xref generation references

Address maintainer feedback on the existing PR. Preserve upstream work and document the tested scope and remaining validation limits.

* M1: cover repaired generations and freed-slot round trips

Address maintainer feedback on the existing PR. Preserve upstream work and document tested scope and validation limits.

* M1: document generation repair and bounded diagnostics

Address maintainer feedback on the existing PR. Preserve upstream work and document tested scope and validation limits.

* M1: record generation repair regression evidence

Address maintainer feedback on the existing PR. Preserve upstream work and document tested scope and validation limits.

* M1: document bounded COS generation repair

Address maintainer feedback on the existing PR. Preserve upstream work and document tested scope and validation limits.

* M1: record generation repair parity evidence

Address maintainer feedback on the existing PR. Preserve upstream work and document tested scope and validation limits.

* fix(cos): preserve repaired generations through preflight and saves

Keep accepted xref/header aliases across repair-aware edits and snapshots, canonicalize full-save identities, and retain bounded generation diagnostics from older revisions. Add COS, writer/encryption, and real preflight regression coverage.

* test(preflight): assert repaired aliases share saved identity

Address the review nitpick by comparing reopened HeaderImage and RowImage references after damaged full saves, for classic/packed output and edited/restored snapshots. Focused preflight regression and rustfmt check pass.

* M14: update certificate dependencies for RustSec advisories

Bump rustls-webpki to0.103.16 and webpki-root-certs to1.0.10. Preserve all other locked packages and dependency lists, manifests, Git pins, and advisory policy.

---------

Co-authored-by: MMexicann <MMexicann@users.noreply.github.com>
Co-authored-by: Codex <noreply@openai.com>
Co-authored-by: FredApps <FredApps@users.noreply.github.com>
2026-11-05 09:28:43 +01:00
mtlcl410andClaude Opus 5.5 1f3fc2ce92 M11: PDF/A verify checks XMP extension schema descriptions (6.6.2.3.3)
Every pdfaExtension:schemas description needs its entries: a schema its
schema, namespaceURI and prefix; a property its name, valueType,
category and description; a value type its type, namespaceURI, prefix,
description and field; a field its name, valueType and description.
Each description namespace is written with its own prefix. One pass over
the metadata streams serves this check and the value types.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pq7HyDBXygTf7jcqdsjcfn
2026-11-05 16:20:56 +08:00
mtlcl410 7b492b9943 Merge branch 'fix/pdfa-xmp-value-types' into fix/pdfa-xmp-exif-types 2026-11-05 12:49:49 +08:00
mtlcl410andClaude Opus 5.5 7bce37fefc M11: PDF/A verify takes no array from a property whose RDF attributes make its value something else (6.6.2.3.1)
An rdf:parseType or rdf:resource on a property element makes its value a
resource or another literal, not the rdf:Seq, rdf:Bag or rdf:Alt it holds.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pq7HyDBXygTf7jcqdsjcfn
2026-11-05 12:48:27 +08:00
mtlcl410 e09f1adf30 Merge branch 'fix/pdfa-xmp-value-types' into fix/pdfa-xmp-exif-types 2026-11-05 12:32:43 +08:00