Commit Graph
3848 Commits
Author SHA1 Message Date
mtlcl410andClaude Opus 5.5 dcef0aebff M8: bound the removed text kept for the metadata check per document (#2448)
The run and byte limits were per page, and a glyph's /ToUnicode text can
be 256 UTF-16 units, so a short content stream could keep gigabytes of
removed text across pages. The document now keeps at most 16 MiB; past
that the rest is not kept and the metadata check fails closed, as for any
other text it couldn't keep (CodeRabbit's retained concern on #2539).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pq7HyG234xeYkJfr41E6iP
2026-11-02 23:36:21 +08:00
mtlcl410andClaude Opus 5.5 4bfea3ade6 M8: protect.apply-redactions notes and evidence cover the second review round (#2448)
Letters-and-digits matching, NFKC, FF FE strings as UTF-16LE, and the
PDF/A / PDF/UA identification written back or reported lost; what still
isn't done (remaining /Info entries aren't mirrored into the new packet).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pq7HyCfwzyRXj4VfQAVVdv
2026-11-02 01:17:24 +08:00
mtlcl410andClaude Opus 5.5 6ce5b5fe43 M8: a removed document XMP packet's PDF/A and PDF/UA identification is written back, or reported lost (#2448)
#2539 review: the scrub removes the catalog's XMP packet whole when it holds
the removed text, and with it the file's PDF/A and PDF/UA claims, which
Report didn't say. The identification (pdfaid part, conformance, amd, rev;
pdfuaid part, rev) is now read by namespace (roxmltree, already in the build
through pdfcraft-xfa), each value kept only when it is the short code it must
be and doesn't hold the removed text (one-character codes always), and
written back in a packet holding nothing else, with a fixed pdfuaid extension
schema under PDF/A-1 to -3 (left out, with the PDF/UA claim, if the redacted
words are among its words). Report::identification says, per standard,
None / Kept / Lost; the engine passes it on as
EditNotice::RedactionIdentification, the Apply notification says it after the
count, and redact_apply returns identification { pdfa, pdfua }.

Tests (redact): the_identification_of_a_removed_packet_is_written_back,
a_packet_without_identification_is_only_removed,
an_identification_that_cannot_be_kept_is_reported_lost,
unsearched_text_keeps_only_one_character_codes,
the_extension_schema_is_left_out_when_it_uses_a_redacted_word; engine
applied_redactions_report_the_pdfa_identification_written_back; automation
redact_apply_reports_the_identification_written_back; ui-egui
applying_says_the_pdfa_identification_was_written_back. With the write-back
replaced by "nothing kept", the redact tests fail (Kept expected, None
found); with the notice not pushed, the engine, automation and UI tests fail.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pq7HyCfwzyRXj4VfQAVVdv
2026-11-02 01:16:34 +08:00
mtlcl410andClaude Opus 5.5 17a9345064 M8: an FF FE text string is searched as UTF-16LE, in /Info and the places applying leaves (#2448)
#2539 review: ISO 32000-2 §7.9.2.2.1 defines text strings in PDFDocEncoding,
UTF-16BE (FE FF) and UTF-8 (EF BB BF) only, so an FF FE string was read
through PDFDocEncoding and Cyrillic or CJK text in it could never match.
It is now read as UTF-16LE for the search (fail-closed), in the /Info scrub
and in the bookmark, attachment and comment counts.

Test: a_utf16le_string_is_searched_as_utf16le (failed before: 0 /Info
entries removed; with only the count reverted, bookmarks 0 instead of 1).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pq7HyCfwzyRXj4VfQAVVdv
2026-11-02 00:56:20 +08:00
mtlcl410andClaude Opus 5.5 38030a7d54 M8: the metadata check compares NFKC, lower-case text, so Unicode forms can't hide the removed text (#2448)
#2539 review: a decomposed "Müller" in a UTF-16BE /Title, a U+FB01 ligature
from a ToUnicode map and full-width letters never matched their plain forms.
Both sides are now normalized to NFKC and lower case (unicode-normalization,
already in the build through pdfcraft-crypt's stringprep, so no new crate).
Normalized text more than four times its input's length (U+FDFA and the like)
isn't searched: it counts as holding the text.

Tests: unicode_forms_of_the_removed_text_match (failed before: Title, Subject
and Keywords kept), a_value_that_normalizes_to_far_more_text_counts_as_holding_it
(failed with the growth limit raised to 100: 0 removed).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pq7HyCfwzyRXj4VfQAVVdv
2026-11-02 00:54:23 +08:00
mtlcl410andClaude Opus 5.5 fdcc569094 M8: the metadata check also compares letters and digits alone, so spacing and TJ tracking can't hide the removed text (#2448)
#2539 review: a heading tracked with TJ numbers ([(B) -300 (L) -300 ...] TJ)
was collected as "B L U E F I N", which neither held "Bluefin" nor had a word
of three letters, and a value spelled "Blue fin" or "BLUE-FIN" didn't hold the
term "bluefin". A TJ gap can't be told from a word space, so the glyph ends stay
as they are; instead every term with three letters or digits is also looked
for by its letters and digits alone, and a value is part of a run when its
letters and digits are, starting and ending at the run's word edges ("True"
still isn't part of "untrue"). It over-matches only towards removal.

Tests: a_heading_tracked_with_tj_numbers_matches_the_metadata,
a_value_spaced_or_hyphenated_otherwise_matches (both failed before: /Title
kept, metadata 0).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pq7HyCfwzyRXj4VfQAVVdv
2026-11-02 00:51:48 +08:00
mtlcl410andClaude Opus 5.5 3e025b9143 M8: the places applied redactions leave holding the removed text are an EditNotice (#2448)
Main's `EditNotice` is "something the last edit did that the user should hear
about", set by `Session::apply` and cleared by the next edit, undo and redo,
which is what the PR's separate `redaction_elsewhere` field did by hand. It is
now `EditNotice::RedactionElsewhere(Elsewhere)`, pushed when a place is counted
or the text couldn't be searched for: tools list it in `warnings` with the
other notices, the interface says it through the same path, and
`Document::redaction_elsewhere()` gives `redact_apply` and the Apply dialog the
counts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pq7HyCfwzyRXj4VfQAVVdv
2026-11-02 00:44:54 +08:00
mtlcl410andClaude Opus 5.5 069f55eb12 Merge storytold/pdfcraft main into fix/redact-metadata-2448
Conflict in crates/engine/src/document.rs: main turned `edit_notices` into
`Vec<EditNotice>`; the PR's `redaction_elsewhere` field is kept beside it in
this merge, and the next commit makes it an `EditNotice` variant.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pq7HyCfwzyRXj4VfQAVVdv
2026-11-01 23:58:34 +08:00
mtlcl410andClaude Opus 5.5 4dbc4fac69 M8: the apply notification says where the removed text is still held (#2448)
After "Applied N redaction marks…", the same notification names the bookmark titles,
attachments, comments and other metadata streams that still hold the redacted text, and points
to Remove hidden information. New English templates; untranslated text shows in English. The
protect.apply-redactions parity note and evidence say what is reported and what is still left.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pq7HyCfwzyRXj4VfQAVVdv
2026-11-01 18:31:52 +08:00
mtlcl410andClaude Opus 5.5 d37bde8c3b M8: Apply redactions passes on where the removed text is still held; redact_apply returns it (#2448)
The document keeps the last apply's Report::still_holding as redaction_elsewhere (re-exported as
RedactionElsewhere), cleared by the next edit, undo or redo as edit_notices is. redact_apply
returns it as still_holding with the four counts, their total and unsearched.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pq7HyCfwzyRXj4VfQAVVdv
2026-11-01 18:31:52 +08:00
mtlcl410andClaude Opus 5.5 1fd2ff31bb M8: test that a form whose content can't be decoded clears the metadata (#2448)
The unread-form branch was tested for a form nested past the depth limit only; a form under a
mark whose filter can't be decoded is removed unread too, and now has an end-to-end test, seen
failing with that branch's flag removed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pq7HyCfwzyRXj4VfQAVVdv
2026-11-01 18:09:13 +08:00
mtlcl410andClaude Opus 5.5 81d629d1ff M8: applying redactions counts the bookmarks, attachments, comments and XMP that still hold the removed text (#2448)
Report::still_holding (Elsewhere) counts the places apply leaves as they are that still hold the
removed text: bookmark titles, attachment names, file names and descriptions, the text and authors
of the comments that remain, and XMP on objects other than the catalog and the pages. Nothing is
changed; Remove hidden information removes them. The text is matched as the metadata check
matches it (one Search type now serves both), with its own work limit. When the removed text
couldn't be searched for, every place holding any text counts and `unsearched` says so. The walks
read each outline item and name-tree node once, within caps.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pq7HyCfwzyRXj4VfQAVVdv
2026-11-01 17:51:37 +08:00
mtlcl410andClaude Opus 5.5 ca4ddcfb90 M8: a test for each way the metadata check fails closed; XMP is decoded strictly (#2448)
End-to-end tests for a removed run over 64 KiB, more than 20,000 terms, a run over 4,096
characters, and XMP that is corrupt, cut short, behind two filters, over 16 MiB or in another
encoding. Each was seen failing with its guard removed or loosened.

The corrupt and cut-short cases showed that the tolerant decoder returned the part of the packet
before the damage, which was then searched as if it were the whole packet. XMP is now decoded
strictly, and a packet behind more than one filter goes unread.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pq7HyCfwzyRXj4VfQAVVdv
2026-11-01 17:46:19 +08:00
Dylan M. Taylor 47f42ba07b ci: grant packages write permission to release workflow 2026-10-31 23:43:03 -04:00
FredApps eea00a6186 Merge pull request #2088 from srt8hellcat2-ui/fix/1577-optional-page-edge-shadows-integration
M3: Add optional page-edge shadows setting (fixes #1577)
2026-10-31 23:42:20 +01:00
FredApps f2e1a8ce29 Merge branch 'main' into fix/1577-optional-page-edge-shadows-integration 2026-10-31 23:38:40 +01:00
FredApps a471cb1664 Merge pull request #1433 from srt8hellcat2-ui/feature/two-paged-cli-1354
M3: add optional --two-paged CLI flag (fixes #1354)
2026-10-31 23:35:31 +01:00
FredApps 19c96011b2 Merge pull request #2212 from srt8hellcat2-ui/feat/license-check-stage1
Add automated licensing validation for bundled assets (#2175)
2026-10-31 23:27:03 +01:00
FredApps 2e853c5fe0 Merge pull request #4279 from srt8hellcat2-ui/fix-3407-rewrite-after-page-delete
Rewrite an unsigned file in full when saving after deleting pages
2026-10-31 23:24:48 +01:00
FredApps 9af62ceb38 Isolate UI frame-budget measurements under nextest 2026-10-31 23:07:05 +01:00
Combiler01 b77699a22b test(optimize): accept Flate or CCITT compression in monochrome scan test 2026-10-31 22:50:50 +01:00
Combiler01 af03f08494 test(optimize): accept Flate or CCITT compression in monochrome scan test 2026-10-31 22:50:50 +01:00
Combiler01 0475725247 test(optimize): accept Flate or CCITT compression in monochrome scan test 2026-10-31 22:50:50 +01:00
Combiler01 9a655ddb2d test(optimize): accept Flate or CCITT compression in monochrome scan test 2026-10-31 22:50:50 +01:00
FredApps e5f21f2dbb Keep licensing checks below the current complexity gate 2026-10-31 22:26:16 +01:00
FredApps 1d5ce9d7a9 Update shadow regression wheel events and retain upstream parity notes 2026-10-31 22:26:16 +01:00
FredApps fdcf66d5f6 Apply licensing validation to newly added upstream Lucide icons 2026-10-31 22:16:52 +01:00
FredApps 50780519e3 Merge current main into PR2212 and reconcile license inventory and shared CI 2026-10-31 22:14:35 +01:00
FredApps bad4c81800 Merge current main into PR2088 and port shadow preference to split UI modules 2026-10-31 22:13:25 +01:00
FredApps 286a3c6eee Merge current main into PR1433 and preserve launch override across module splits 2026-10-31 22:12:05 +01:00
FredApps 7165ff1ace Merge current main into PR4279 and retain unsigned delete-save policy 2026-10-31 22:09:56 +01:00
Dylan M. Taylor 13655d0992 packaging(flatpak): add OCI image build and GHCR publishing helper (#5526) 2026-10-31 15:33:25 -04:00
Dylan M. Taylor f137a289ba Merge pull request #5522 from aiongg/docs-tidy
docs: tidy agent, contributor and asset docs
2026-10-31 01:06:25 -04:00
Dylan M. Taylor 4a5f9ced2d Merge pull request #5527 from aiongg/update-result-dialog
Updates: shared check-result dialog from craft-update
2026-10-31 01:05:42 -04:00
aiongg 635a840164 updates: show check results with craft-update's CheckResultDialog 2026-10-31 04:43:07 +00:00
aiongg da4cc2c145 docs: tidy wording 2026-10-31 04:25:36 +00:00
aiongg 44ddb348a9 docs: tidy agent, contributor and asset docs 2026-10-31 04:17:20 +00:00
Brandon ThomasandClaude Opus 5.5 24bb85308e Release 0.16.1
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
v0.16.1
2026-10-30 23:25:37 -04:00
Brandon ThomasandClaude Opus 5.5 35c187ff19 Flatpak bundle: skip the debuginfo pass manifest-wide (runner has no eu-strip)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 23:25:35 -04:00
Brandon ThomasandClaude Opus 5.5 8f16855097 Release 0.16.0
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 23:22:57 -04:00
Brandon ThomasandClaude Opus 5.5 4b70916883 Flatpak bundle: skip the debuginfo pass for cups-client (runner has no eu-strip)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 23:22:50 -04:00
skylar taylor-barrick 65ff3a00c0 Merge pull request #4172 from songzhihui/fix/windows-cjk-viewer
M2: continue CJK viewer fallback for Windows GBK PDFs
2026-10-30 18:45:08 -06:00
Dylan M. Taylor ec33924e80 fix(flatpak): allow reading launcher version pins (#5490)
* fix(flatpak): allow reading launcher version pins

* fix(flatpak): allow reading launcher version pins
2026-10-30 20:12:04 -04:00
mtlcl410andClaude Opus 5.5 409477067a M8: the redact README lists every fail-closed trigger and the metadata it doesn't scrub (#2448)
Review on #2539 (nitpick): the README named only the collection limit
and unreadable XMP as fail-closed cases. It now lists all of them (the
run and run-length limits, a removed glyph with unknown text, a form
XObject removed unread past the depth limit or unreadable, the term
limits, the search work limit, oversized or undecodable XMP) and the
metadata the check leaves to Sanitize: XMP on objects other than the
catalog and pages, bookmark titles, and attachments.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pq7HyCfwzyRXj4VfQAVVdv
2026-10-31 08:05:51 +08:00
songzhihui a57095c872 M2: assert exact GBK glyph rasters for installed Chinese families 2026-10-31 01:39:00 +08:00
songzhihui 9447cdc810 M2: merge main and resolve CJK viewer integration conflicts 2026-10-31 01:14:02 +08:00
skylar taylor-barrick fa5f9f8c3b Merge pull request #5426 from FredApps/chore/parity-integration-20261030
Integrate 27 reviewed PDF editing, forms and optimizer PRs
2026-10-30 09:24:25 -06:00
FredApps 6772772440 test: accept preserved CCITT filter arrays in lossless regression 2026-10-30 15:52:18 +01:00
FredApps 7fe33d1cbd test: verify conservative review fixes across rendering and automation 2026-10-30 15:32:44 +01:00
FredApps 4791cacd2c test: qualify conservative tone retention and format review regressions 2026-10-30 14:55:44 +01:00