Commit Graph
100 Commits
Author SHA1 Message Date
Dylan M. Taylor 7ca642980a docs: sync Craft App Suite list with ArtCraft Launcher 2026-11-01 12:29:59 -05:00
Dylan M. Taylor 47f42ba07b ci: grant packages write permission to release workflow 2026-10-31 23:43:03 -04: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
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
Dylan M. Taylor 1d1cbc4ec9 UPD.1: honor app pretend versions in update checks (#5397) 2026-10-30 02:35:18 -04:00
Dylan M. Taylor 3517d05b47 Update prompt shows the app icon and accent color instead of a letter (#5388)
UPDATE_APP (native builds; craft-update is a native-only dependency) carries our 128 px icon and accent (#b70228, its red, from the icon (#5245)). The updater, the self-update
helper and craft-update's startup prompt all get them through crate::UPDATE_APP; the
prompt draws the icon, the accent and "by ArtCraft" (craft-update's default developer).

craft-update is pinned to storytold/craft-libs main at 1065653e7 (#434).
Clippy fixes for Rust 1.99 in untouched code (same logic):
- crates/edit/src/images.rs
- crates/forms/src/appearance.rs
2026-10-30 01:27:58 -04:00
Dylan M. Taylor f76dbb9e8c deps: bump tar, zip, roxmltree, rustls-webpki and symphonia to their latest versions (#5381)
- `zip`: 9.1.0 → 9.1.3

Requirement `roxmltree` 0.20 → 0.21: `ParsingOptions` gained `entity_resolver` (initializers take `..Default::default()`, i.e. none, as before) and is no longer `Copy` (two functions build it with a closure, the pattern merge.rs already used).
2026-10-29 22:21:27 -04:00
Dylan M. Taylor 834a4daf9c CI: workflows only call craft-common-actions at @main (#5378)
AGENTS.md (and CLAUDE.md where present) gets a CI workflows section: workflows only call
craft-common-actions at @main, with no other jobs; feature and fix PRs don't touch CI and
link or open a craft-common-actions issue (a PR only for a small fix that is safe for
every app and does not increase CI time); legacy jobs
aren't added to and move only as their own task, staying until a shared workflow runs them.

windows-arm64.yml moves from its SHA pin to @main. The pinned revision is on
craft-common-actions main and the workflow (and the actions it calls) is identical
there, so nothing changes in behaviour.
2026-10-29 22:10:15 -04:00
Dylan M. Taylor 726ecf2625 packaging: Flatpak finds and prints to CUPS printers (#5346)
* packaging: Flatpak finds and prints to CUPS printers

The Print dialog listed no printers in the Flatpak: the runtime has libcups but not
lpstat/lp, the sandbox couldn't reach the CUPS socket, and driverless network printers
(lpstat -e) need Avahi. Bundle lpstat/lp/lpoptions from CUPS 2.4.20 (Apache-2.0,
statically linked, licence installed) and grant --socket=cups and
--system-talk-name=org.freedesktop.Avahi in both manifests.

* packaging: Flatpak reads the user's CUPS settings (~/.cups, read-only)

Review (CodeRabbit): without it the sandbox's lp/lpstat ignore the user's default
printer and saved options (lpoptions) and a print server named in their client.conf.

* packaging: Flatpak CUPS tools reach the host socket when client.conf names a custom path

Review: Flatpak mounts the host's CUPS socket at /var/run/cups/cups.sock whatever
path ~/.cups/client.conf or CUPS_SERVER names, so lp/lpstat/lpoptions now run through
a wrapper that points a socket path missing in the sandbox there. Server names
(remote servers) and sockets that exist are left alone. Tested in the sandbox:
CUPS_SERVER=/run/custom/cups.sock lists the host's printers through the wrapper and
none without it; a host name is passed through unchanged.

* packaging: redirect a custom CUPS socket only when it is the one Flatpak mounted

Review (CodeRabbit): Flatpak picks the socket it mounts at /var/run/cups/cups.sock
with stricter rules than CUPS (flatpak-run-cups.c: a socket CUPS_SERVER, else the
first line spelled exactly "ServerName /path" in ~/.cups/client.conf, else the
default), while CUPS reads the keyword in any case and takes the last ServerName. The
wrapper now redirects only when CUPS' socket is the one Flatpak chose, so a job can't
reach a different server; otherwise CUPS fails on the missing path.

* packaging: never redirect a CUPS_SERVER the sandbox was given

Review (CodeRabbit): Flatpak picks the socket it mounts from the host's CUPS_SERVER,
so one set by flatpak run --env or an override may not be what it mounted. The
wrapper now leaves any CUPS_SERVER alone and redirects only a client.conf socket that
matches Flatpak's choice; otherwise CUPS fails on the missing path instead of
reaching a different server.

* packaging: point CUPS at the mounted socket only when it is the one Flatpak chose, else fail

Review (CodeRabbit): with a custom socket listed first and the default last in
~/.cups/client.conf, Flatpak mounts the custom one at /var/run/cups/cups.sock while
CUPS picks the last line, finds that path, and talks to the custom server. The
wrapper now compares CUPS' socket with Flatpak's choice even when the path exists:
equal, CUPS is pointed at the mount; different, the tool fails with an error instead
of reaching another server.
2026-10-29 18:48:45 -04:00
Dylan M. Taylor c735fb7da5 Make PdfCraft's app color red (#5245)
* Make PdfCraft's app colour red

The icon tile, the Windows PDF file icon's badge and lines, the DMG background and the README
badges move from green #12a58a to crimson #b70228 (darker shade #8a011e, fold #f3cfd6).
Every PNG, .ico and .icns is re-rendered from the edited master SVGs with packaging/icons.sh
and resvg 0.47; the .icns is written with Pillow because iconutil is macOS-only, with
iconutil's size set. The DMG background is re-rendered with generate.py; its .DS_Store is
unchanged. ATTRIBUTION.toml hashes updated; cargo xtask assets passes.

* Fix OCR model attribution hashes
2026-10-29 12:13:07 -04:00
Dylan M. Taylor 7555be3c7e Honor CARGO_BUILD_TARGET in FreeBSD packaging for aarch64 release builds (#5205)
The script already validated CARGO_BUILD_TARGET and named the archive after the arch, but
cargo build ignored it, so a cross build compiled for the host. Pass --target, resolve
host-tuple to the build host's triple first, and skip the --version smoke run for any
CARGO_BUILD_TARGET build (an aarch64 binary cannot run on the x86_64 VM).
2026-10-28 15:48:56 -04:00
Dylan M. Taylor 67d4f18179 Grant network access so update checks can reach GitHub (#5189) 2026-10-28 13:17:18 -04:00
Dylan M. Taylor 3932ee0639 Enforce Rust coding standards via Clippy (#4897)
* Refactor annot for strict Clippy checks

* Refactor automation for strict Clippy checks

* Refactor cos for strict Clippy checks

* Refactor edit for strict Clippy checks

* Refactor engine for strict Clippy checks

* Refactor export for strict Clippy checks

* Refactor forms for strict Clippy checks

* Refactor js for strict Clippy checks

* Refactor organize for strict Clippy checks

* Refactor pdfcraft-cli for strict Clippy checks

* Refactor preflight for strict Clippy checks

* Refactor print for strict Clippy checks

* Refactor redact for strict Clippy checks

* Refactor render for strict Clippy checks

* Refactor sign for strict Clippy checks

* Refactor ui canvas for strict Clippy checks

* Refactor ui commands for strict Clippy checks

* Refactor ui dialogs for strict Clippy checks

* Refactor ui support for strict Clippy checks

* Refactor ui tools for strict Clippy checks

* Refactor ui workflows for strict Clippy checks

* Refactor xfa for strict Clippy checks

* Refactor xfdf for strict Clippy checks

* Enforce workspace Clippy standards and document lint policy

* Fix menu overflow and form pointer handling

* Group annotation, form and document operation parameters

* Group signing and timestamp validation inputs

* Group demo form field properties

* Group UI interaction and rendering parameters

* Restore translated security and shortcut labels

* Fix platform-gated imports for Windows and wasm builds

* Qualify signing calls for macOS and Windows builds

* Restore the preflight check flow and the overflow menu title
2026-10-27 20:51:13 -04:00
Dylan M. Taylor e4966354ee Restore the preflight check flow and the overflow menu title 2026-10-28 00:21:28 +00:00
Dylan M. Taylor ad95afb0f8 Qualify signing calls for macOS and Windows builds 2026-10-28 00:21:27 +00:00
Dylan M. Taylor ef894ae6b8 Fix platform-gated imports for Windows and wasm builds 2026-10-28 00:14:57 +00:00
Dylan M. Taylor 76ce895478 Restore translated security and shortcut labels 2026-10-27 23:33:26 +00:00
Dylan M. Taylor 31833c992d Group UI interaction and rendering parameters 2026-10-27 23:25:40 +00:00
Dylan M. Taylor 775d6a4a19 Group demo form field properties 2026-10-27 23:25:40 +00:00
Dylan M. Taylor 5fecdb9cee Group signing and timestamp validation inputs 2026-10-27 23:25:40 +00:00
Dylan M. Taylor 81c63c037a Group annotation, form and document operation parameters 2026-10-27 23:25:39 +00:00
Dylan M. Taylor 63bc58a3d5 Fix menu overflow and form pointer handling 2026-10-27 23:16:56 +00:00
Dylan M. Taylor d95ff3898d Enforce workspace Clippy standards and document lint policy 2026-10-27 23:12:52 +00:00
Dylan M. Taylor 92bc2f9acd Refactor xfdf for strict Clippy checks 2026-10-27 23:12:52 +00:00
Dylan M. Taylor 9530dbb3e8 Refactor xfa for strict Clippy checks 2026-10-27 23:12:52 +00:00
Dylan M. Taylor 2ca92751cf Refactor ui workflows for strict Clippy checks 2026-10-27 23:12:52 +00:00
Dylan M. Taylor 21cae663d1 Refactor ui tools for strict Clippy checks 2026-10-27 23:12:52 +00:00
Dylan M. Taylor 2d27306a8d Refactor ui support for strict Clippy checks 2026-10-27 23:12:52 +00:00
Dylan M. Taylor bf89bf918c Refactor ui dialogs for strict Clippy checks 2026-10-27 23:12:52 +00:00
Dylan M. Taylor f796c71abe Refactor ui commands for strict Clippy checks 2026-10-27 23:12:52 +00:00
Dylan M. Taylor e7a60f2fd4 Refactor ui canvas for strict Clippy checks 2026-10-27 23:12:52 +00:00
Dylan M. Taylor 074d4f3111 Refactor sign for strict Clippy checks 2026-10-27 23:12:51 +00:00
Dylan M. Taylor a11909551d Refactor render for strict Clippy checks 2026-10-27 23:12:51 +00:00
Dylan M. Taylor 33e23da8a9 Refactor redact for strict Clippy checks 2026-10-27 23:12:51 +00:00
Dylan M. Taylor bc89733725 Refactor print for strict Clippy checks 2026-10-27 23:12:51 +00:00
Dylan M. Taylor c043c82531 Refactor preflight for strict Clippy checks 2026-10-27 23:12:51 +00:00
Dylan M. Taylor 530e2a2645 Refactor pdfcraft-cli for strict Clippy checks 2026-10-27 23:12:51 +00:00
Dylan M. Taylor f40a57878b Refactor organize for strict Clippy checks 2026-10-27 23:12:51 +00:00
Dylan M. Taylor a0598816d2 Refactor js for strict Clippy checks 2026-10-27 23:12:51 +00:00
Dylan M. Taylor 4965e23bfe Refactor forms for strict Clippy checks 2026-10-27 23:12:51 +00:00
Dylan M. Taylor 5e75b9c3e6 Refactor export for strict Clippy checks 2026-10-27 23:12:51 +00:00
Dylan M. Taylor 166f706e3e Refactor engine for strict Clippy checks 2026-10-27 23:12:51 +00:00
Dylan M. Taylor de73c35e17 Refactor edit for strict Clippy checks 2026-10-27 23:12:51 +00:00
Dylan M. Taylor 84c873d2e1 Refactor cos for strict Clippy checks 2026-10-27 23:12:51 +00:00
Dylan M. Taylor 9d97546081 Refactor automation for strict Clippy checks 2026-10-27 23:12:51 +00:00
Dylan M. Taylor 7d1ed99f51 Refactor annot for strict Clippy checks 2026-10-27 23:12:50 +00:00
Dylan M. Taylor f94668f1c8 fix(sonar): clear css:S9441 and S3776 in forms actions 2026-10-26 16:01:32 -04:00
Dylan M. Taylor 32a9af4d08 proposal(redact): unlink unused Type 3 glyph programs and fonts on redaction (F-011) 2026-10-26 16:01:29 -04:00
Dylan M. Taylor 13bfbd0761 Merge pull request #4737 from storytold/chore/deps-safe-refresh
chore(deps): bump 11 safe dependency updates
2026-10-25 19:03:52 -04:00
Dylan M. Taylor 83ba28680f build: pin craft-update to craft-libs main (495e597) (#4728)
Picks up the startup prompt without the glyphs a font may lack (storytold/craft-libs#343, #344): the close mark is painted and the version pill is ASCII, so apps that panic on a missing glyph no longer take the prompt down.

Part of tracking issue storytold/craft-libs#319
2026-10-25 17:54:18 -04:00
Dylan M. TaylorandCodebuff cda2d019e3 build: pin craft-update to craft-libs main (495e597) (#4721)
Picks up the update prompt fix that draws its close mark and version pill
without glyphs a font may lack, so the prompt no longer takes the app down
when a bundled face has no ✕ or →.

Part of tracking issue storytold/craft-libs#319

🤖 Generated with Codebuff

Co-authored-by: Codebuff <noreply@codebuff.com>
2026-10-25 17:37:06 -04:00
Dylan M. Taylor 833cd63c8a proposal(redact): prevent retention of confidential vector paths behind clipping (F-008) (#4577)
Partial vector redaction previously hid covered areas with clipping
(`clip_out`, `W/W*`) while retaining the complete original drawing instructions
and painting operators in the content stream. This allowed recipients
to recover confidential outlined text or other vector drawings from
supposedly redacted documents.

This change removes vector paths that intersect redaction marks completely
and refuses partial clip retention, ensuring no confidential geometry is
preserved behind clipping. Report counts are updated to record removed paths.
2026-10-25 16:14:06 -04:00
Dylan M. Taylor 86a4120ae0 feat: startup update prompt modal and direct self-updating (#4654)
* feat: startup update prompt modal and direct self-updating

Help ▸ Check for updates and the check at start run through craft-update's Updater, which replaces the old GitHub fetcher and update source. The check at start is opt-in for the desktop app (test harnesses never reach the network), an install holds back while documents are unsaved, and a finished update closes through the app's quit path. craft-update stays out of the wasm build.

Ref: storytold/craft-libs#319

* test(updates): the prompt's buttons are DOWNLOAD and LATER

* build: pin craft-update to craft-libs main (db19c37)

* fix(updates): run the Windows update helper before argument parsing

* fix(updates): point the parity evidence at the current update tests
2026-10-25 16:00:23 -04:00
Dylan M. Taylor aa9a9105fc fix(redact): remove AcroForm on Hidden::FormFields even when field count is zero (#4571)
* fix(redact): remove AcroForm on Hidden::FormFields even when field count is zero

* fix(redact): report AcroForm presence in scan() and format
2026-10-24 21:07:16 -04:00
Dylan M. Taylor 4c69b8cf88 fix(forms): align has_password_flag traversal depth with field enumeration (#4570)
* fix(forms): align has_password_flag traversal depth with field enumeration

* fix(forms): extend field_chain depth to 64 and fix test formatting
2026-10-24 21:07:09 -04:00
Dylan M. Taylor f4f91d0d5c fix(xfa): require full save when stripping XFA packets (#4568) 2026-10-24 21:03:25 -04:00
9aef0dfb78 refactor(xfa): explicit model imports (Sonar S2208) (#4403)
* refactor(xfa): replace model wildcard imports with explicit names (Sonar S2208)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* fix(xfa): complete explicit model imports

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* fix(xfa): drop unused model imports

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Import Corner, which main's parse.rs now uses

---------

Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-24 10:31:05 -04:00
Dylan M. TaylorandClaude Sonnet 5.5 39d69c3165 refactor(engine): extract quad_score and page_has_form_xobject (Sonar S3776) (#4408)
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-24 10:29:47 -04:00
Dylan M. TaylorandClaude Sonnet 5.5 486949424c refactor(a11y): extract text_spans and xobject_bbox helpers (Sonar S3776) (#4407)
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-24 10:29:43 -04:00
Dylan M. TaylorandClaude Sonnet 5.5 ff267d6883 refactor(xtask): split parity evidence and layers dependency checks (Sonar S3776) (#4406)
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-24 10:29:38 -04:00
Dylan M. TaylorandClaude Sonnet 5.5 c894928e6f fix(demo): showcase font-display, distinct link text, SVG accessible names (Sonar) (#4402)
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-24 04:37:33 -04:00
a047c6ba09 chore: resolve SonarCloud maintainability issues (#4356)
* chore: resolve SonarCloud maintainability issues

* fix(packaging): use verify_sha256 helper function

* style: cargo fmt

* fix: restore wildcard imports and fix method-reference type errors

Revert the glob-import expansions (they missed SomIndices and left unused
imports), revert char::is_ascii_digit where the iterator yields char by
value, and pass the content slice to prune_doomed_xobjects as &[Vec<u8>].

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Keep XObject decodability check without binding content in interp

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Dylan Taylor <dylan@craftmaker.dev>
2026-10-23 23:28:18 -04:00
Dylan M. Taylor a2ec27b477 ci(sonar): don't cancel superseded runs on main, so coverage is published (#4321) 2026-10-23 17:06:26 -04:00
Dylan M. Taylor aea5e78e66 release: the git-sources gate moves into craft-common-actions (storytold/craft-common-actions#78) (#4292)
The check is shared at release.yml@main now; keep only the reusable call.
2026-10-23 14:41:20 -04:00
Dylan M. Taylor 60643020b6 Merge pull request #4244 from dylanmtaylor/fix/high-severity-redact-sign
fix(redact,sign,cos): close the still-open high-severity scan findings
2026-10-23 10:25:51 -04:00
Dylan M. Taylor 5162da1b9f fix(sign): a widget counts as signed only when its /V resolves to a dictionary 2026-10-23 10:22:33 -04:00
Dylan M. Taylor 39ee93fe70 fix(redact,sign): address review — pop-up replies, signed-role deletions, widget role from signed revision 2026-10-23 10:11:10 -04:00
Dylan M. Taylor dad86bf9f5 fix(redact,sign,cos): close high-severity findings from the agent scan
Redact: refuse Redact marks written in place; remove replies and pop-ups listed on
other pages; delete form fields by object, not name; resolve Do by its last operand
like the renderer; sanitize drops PCAdded and flattens widgets before hidden-content
cleanup. Sign: freed signed objects and edits to an already-signed widget are
modifications. Cos: only reading trusts /Type /XRef to skip encryption.
2026-10-23 10:11:10 -04:00
Dylan M. Taylor 90bd6660f7 Merge pull request #4220 from Jayesh-Prajapati9/chore/ctutils-rustsec-2026-0385
M14: update ctutils to 0.4.5 for RUSTSEC-2026-0385
2026-10-23 10:11:03 -04:00
Dylan M. Taylor 0dc77fe4ed Merge pull request #4129 from aiongg/fix/coderabbit-c5-forms-misc
fix(xfdf, sign, preflight, engine, forms, measure, annot): bound repeated work in form exchange, preflight and export, and check what imports and time stamps claim
2026-10-22 22:50:29 -04:00
Dylan M. Taylor 5f7b9e241b Merge pull request #4109 from aiongg/fix/coderabbit-a1-audit
fix(audit): find covers the audit missed, bound its work and honour the copy permission
2026-10-22 22:50:24 -04:00
Dylan M. Taylor 7fa38de186 Merge pull request #4170 from dylanmtaylor/fix/sonar-shell-scripts
fix(packaging): use [[ tests and name positional parameters (SonarCloud shelldre:S7688, S7679, S7682, S131)
2026-10-22 22:48:47 -04:00
Dylan M. Taylor 1d29f0673c Merge pull request #4169 from dylanmtaylor/chore/sonar-scope-vendor-and-spec-hashes
chore(sonar): exclude vendored crates and the spec-mandated MD5/RIPEMD-160 (SonarCloud rust:S4790)
2026-10-22 22:48:42 -04:00
Dylan M. Taylor e93f11e81e fix(packaging): use [[ tests and name positional parameters in the scripts (SonarCloud shelldre:S7688, S7679, S7682, S131)
Every packaging script runs under bash, so [[ ]] is available. Name the positional
parameters of sha256, render and has, end env.sh's functions with an explicit return
(bare, so the exit status is unchanged), and give the build-label case a default arm.
2026-10-22 22:40:05 -04:00
Dylan M. Taylor bd9030b271 chore(sonar): exclude vendored crates and the spec-mandated MD5/RIPEMD-160 (SonarCloud rust:S4790)
vendor/ is third-party code kept close to upstream (vendor/README.md), so SonarCloud's
186 findings there are not ours to restyle. MD5 in crates/crypt is what ISO 32000's
standard security handler mandates, and RIPEMD-160 in crates/sign is a digest existing
signatures can name; both S4790 findings are scoped to those two files.
2026-10-22 22:36:03 -04:00
Dylan M. Taylor 7345e5f5de Merge main into fix/coderabbit-a1-audit
Keep this branch's budgeted audit() and read lines with main's
glyph_text_lines, so /ActualText cannot hide text under a cover.
2026-10-22 22:20:45 -04:00
Dylan M. Taylor 07a9109fed Merge remote-tracking branch 'origin/main' into HEAD 2026-10-22 22:07:20 -04:00
Dylan M. Taylor 93b25f67a6 Merge main into fix/coderabbit-c5-forms-misc
Keep the Ops iterator from this branch and carry main's long-number skip
(MAX_RETRIED_TOKEN) into its operand error path.
2026-10-22 22:07:19 -04:00
Dylan M. Taylor de91632934 Merge pull request #4151 from aiongg/fix/coderabbit-c2-edit-organize
fix(edit,organize,create): bound the work hostile files cause in editing, page organizing and image import
2026-10-22 21:57:13 -04:00
Dylan M. Taylor 684226713a Merge remote-tracking branch 'origin/main' into HEAD
# Conflicts:
#	crates/audit/src/tests.rs
2026-10-22 21:42:41 -04:00
Dylan M. Taylor d31a96f46f Merge pull request #4121 from aiongg/fix/coderabbit-c1-js-xfa
fix(js, xfa): bound the text and work that form scripts and XFA data can multiply
2026-10-22 21:39:08 -04:00
Dylan M. Taylor 8ee1ac0c58 Merge pull request #4117 from aiongg/fix/coderabbit-b-caps
fix(limits): bound the decoding and listing work that repeated references and small inputs multiply
2026-10-22 21:38:59 -04:00
Dylan M. Taylor 3cee9f338f Merge pull request #4128 from aiongg/fix/coderabbit-c4-core
fix(cos, content, filters, crypt, model, render, print, a11y): bound the work that repeated keys, streams and page values multiply
2026-10-22 21:38:37 -04:00
Dylan M. Taylor f7a3a52fad Merge pull request #4114 from aiongg/fix/coderabbit-b-shared
fix(cos): one decode budget per page walk, so repeated stream references cannot multiply decoding
2026-10-22 21:38:15 -04:00
Dylan M. Taylor 80b7d21525 fix: add generic font-family fallbacks in demo (SonarCloud css:S4649)
Each font-family in assets/demo/showcase.html named only a specific font with
no generic fallback. Add an appropriate generic (serif/sans-serif/monospace/
cursive/math) so text still renders if the specific face is unavailable.
2026-10-22 07:09:59 -04:00
Dylan M. Taylor dbc7130b36 ci: pin GitHub Actions to full commit SHA (SonarCloud githubactions:S7637) (#3932)
Pin third-party actions to full-length commit SHAs (with version comments)
instead of mutable tags/branches to prevent supply-chain tampering via
retagged releases. Resolves SonarCloud rule githubactions:S7637.
2026-10-21 20:14:11 -04:00
Dylan M. Taylor 78ef66636d security: enforce HTTPS on curl downloads (SonarCloud S6506) (#3933)
Add --proto '=https' to curl invocations so redirects cannot downgrade to
plaintext HTTP. Resolves SonarCloud S6506 (shell/docker/githubactions).
2026-10-21 20:13:46 -04:00
Dylan M. Taylor 606c560d24 Use chrono instead of hand-rolled UTC conversion (#3824)
* Use chrono for UTC/calendar conversion instead of hand-rolled copies

Replaces the hand-rolled civil_from_days/days_from_civil copies and the
leap-year/month math around them (log timestamp, PDF /Info dates, ASN.1
UTCTime/GeneralizedTime, FormCalc Date/Num2Date, the Combine modified-time
stamp, the form date picker, and the demo-PDF timestamps) with chrono as a
workspace dependency. The engine's existing chrono (clock) is lifted to the
workspace. Every output format is unchanged and pinned by tests. CLAUDE.md now
says time goes through chrono.

Follow-up to storytold/cadcraft#1785

* Guard chrono date paths: no panic on overflow, no '+' on 5-digit years

Systemic chrono follow-ups to the UTC/calendar PR:

- logging::timestamp and combine_ui::utc_stamp dropped chrono's
  From<SystemTime> (which unwraps internally and panics on a clock past
  year 262143) for the fallible DateTime::from_timestamp, reading an
  out-of-range clock as the epoch, as the old clamping code did.
- timestamp, utc_stamp, pdf_date and the xtask Stamp now write the year
  with {:04} instead of %Y, which prefixes a '+' before years past 9999;
  the old hand-rolled code wrote the plain zero-padded year.
- forms_ui calendar navigation and length, and formcalc days_in, use
  checked_add for the December year successor so y + 1 can't overflow at
  i32::MAX / i64::MAX (reachable from a parsed or persisted date).

Docstrings added to the chrono-touched civil_from_days and Time::from_unix
for the docstring-coverage gate. Tests cover the out-of-range-epoch and
10000-01-01 cases for each.

* Don't build an unrepresentable SystemTime in the far-future test

UNIX_EPOCH + Duration::from_secs(u64::MAX / 2) overflows Windows'
SystemTime and panicked before timestamp() ran, failing the Windows
test job. Build it with checked_add and only assert where it exists.

* Keep FormCalc dates exact past chrono's range

MAX_DAYS accepts day numbers up to 1e8 (years past 270000), but NaiveDate
stops near ±262143, so Num2Date(99000000) and Format fell back to
1900-01-01. days_from_civil, civil_from_days and days_in now have chrono
convert within the date's 400-year Gregorian cycle and add whole cycles
back (via i128), which gives the pre-chrono results for every year. Tests
cover accepted inputs past chrono's range on both sides of the epoch,
through Num2Date and Format, with values from the old formula.

* Bump rustls-webpki and webpki-root-certs for RUSTSEC-2026-0382/0383

rustls-webpki 0.103.15 -> 0.103.16 and webpki-root-certs 1.0.9 -> 1.0.10
(both semver-compatible, lockfile only) drop the distrusted emSign
intermediates and root. Only these two entries change; cargo deny check
advisories passes. Upstream main fails the same check.

* logging/cos/sign/combine/demo: keep extended-year dates, no epoch fallback

For consistency with the stricter no-epoch-fallback rule now agreed across the sibling
chrono PRs (wordcraft#3427, filmcraft#2662): `DateTime::from_timestamp(..).unwrap_or_default()`
changes a timestamp the old code converted past chrono's year 262143 range — it collapses
to 1970-01-01 instead of the real proleptic-Gregorian date. The FormCalc Num2Date path was
already fixed (FredApps approved); this applies the same fix to every remaining conversion.
Each site uses the 400-year Gregorian cycle (146_097 days) with chrono as the only calendar
logic: chrono converts the day within one cycle, whole cycles carry in the year (i128,
saturated into i64). PDF/ASN.1 format-specific year handling is kept exactly as the old code
had it. Verified the cycle result equals the old formula across a wide range and at the extremes.

- apps/pdfcraft/src/logging.rs `timestamp`: cycle `civil_from_days(u64)`; pre-1970 epoch clamp
  and ms/time-of-day format kept. Pins: +10_000_000_000_000 s -> 318857-05-20T17:46:40.000Z
  (was 1970); checked_add u64::MAX/2 s -> 292277026596-12-04T15:30:07.000Z (was epoch).
- crates/cos/src/writer.rs `pdf_date` (i64): cycle converter, no year clamp (old code wrote `y`
  as-is, so a negative year keeps its sign). Pins: pdf_date(10_000_000_000_000)="D:3188570520174640Z",
  pdf_date(-10_000_000_000_000)="D:-3149180813061320Z".
- crates/sign/src/der.rs `Time::from_unix` (i64): cycle converter; the `year` field is a u32, so
  the year is cast `as u32` (wrapping) exactly as the old code did — ASN.1 year width preserved
  byte-for-byte. Pins: from_unix(10e12).year=318857, from_unix(-10e12).year=4_294_652_378,
  from_unix(i64::MAX).year=219_250_468, from_unix(i64::MIN).year=4_075_720_767.
- crates/ui-egui/src/combine_ui.rs `utc_stamp` (u64): cycle converter; pre-1970 epoch clamp kept.
  Pins: utc_stamp(10e12)="318857-05-20 17:46 UTC", u64::MAX/2 s="292277026596-12-04 15:30 UTC".
- xtask/src/demo_pdf/pdf.rs `Stamp::from_unix` (i64): cycle converter, no year clamp. Pins:
  from_unix(10e12).iso="318857-05-20T17:46:40Z"/.pdf="D:3188570520174640Z",
  from_unix(-10e12).iso="-314918-08-13T06:13:20Z".

cos/sign/xtask built, tested (pdf_dates_are_utc_and_byte_identical, der::tests::times,
stamps_round_trip), fmt and clippy clean. pdfcraft-ui-egui and the pdfcraft app can't link
here (unrelated LLVM intrinsic bug in the rten-gemm dependency, 1.98.1), so their logging and
combine_ui functions + tests were copied verbatim into a scratch crate with chrono 0.4.45 and
pass there; fmt --check clean on all five packages. CI builds these on all platforms.

* Don't build a year-318857 SystemTime unchecked in the logging test

Windows' SystemTime only reaches about year 30828, so
UNIX_EPOCH + Duration::from_secs(10_000_000_000_000) panicked before
timestamp() ran and failed the Windows test job. Build it with
checked_add and assert where the platform can hold it. The year-10000
case fits everywhere and stays unconditional.

* Name the 400-year range extension as the one exception to the time rule

The rule said never to hand-roll calendar math, but the range fix
(shifting by whole 400-year Gregorian cycles so dates past chrono's year
range keep their old output) is cycle arithmetic, so the rule and the code
disagreed. The rule now names that exception: the library still computes
month, day and time, and only whole cycles are carried in the year.

* Say the library computes month and day; time-of-day is plain arithmetic

Narrows the range-extension wording: the date library computes the
calendar fields, and splitting seconds into hours, minutes and seconds
is ordinary arithmetic, which is what the code does.
2026-10-21 19:36:46 -04:00
Dylan M. Taylor b1bf1cf01f ci: add sonar-project.properties for CI-based analysis
Marks the project ineligible for SonarCloud Automatic Analysis, resolving the
CI-vs-automatic-analysis conflict so the SonarCloud workflow succeeds.
2026-10-21 16:00:45 -04:00
Dylan M. Taylor 30b8c60b55 ci: add SonarCloud scan via shared reusable workflow
Calls storytold/craft-common-actions/.github/workflows/sonarcloud.yml@main
with secrets: inherit. Adds SonarCloud badge to README where missing and
removes the redundant sonar-project.properties (config now passed by the
reusable workflow).
2026-10-21 15:47:03 -04:00
Dylan M. Taylor 4164951453 Merge pull request #2753 from dylanmtaylor/ci/shared-nix-workflow
ci: switch to shared nix workflow from craft-common-actions
2026-10-21 03:59:40 -04:00
Dylan M. Taylor d7481cca6e Merge remote-tracking branch 'origin/main' into pr-2753
# Conflicts:
#	.github/workflows/nix.yml
2026-10-21 03:41:36 -04:00
Dylan M. Taylor 59a5a83774 docs: add SonarCloud and CodeRabbit badges to README (#3271)
* docs: add SonarCloud and CodeRabbit badges and standardize to flat-square

* docs: put SonarCloud and CodeRabbit badges on their own line
2026-10-20 11:29:59 -04:00
Dylan M. Taylor a8cd797a91 ci: configure Dependabot for Cargo and GitHub Actions (#3304)
* ci: configure Dependabot for Cargo and GitHub Actions

* ci: add Cargo update entry for /crates/filters/fuzz in Dependabot

* ci: consolidate Cargo Dependabot directories in pdfcraft
2026-10-18 15:11:14 -04:00
Dylan M. Taylor 98cbd38a8e Merge pull request #3161 from dylanmtaylor/chore/drop-competitor-references
docs: drop references to competing commercial software
2026-10-18 11:31:27 -04:00
Dylan M. Taylor 9a7824557e docs: use generic office terms and clarify fidelity harness and parity tracking reference 2026-10-18 10:49:21 -04:00
Dylan M. Taylor feb6c38580 docs: drop references to competing commercial software 2026-10-18 10:48:33 -04:00
Dylan M. Taylor cfb71d850e ci: switch to shared nix workflow from craft-common-actions 2026-10-15 23:57:29 -04:00