Repository navigation
pdfcraft: update to upstream main, robustness fixes - #502
Merged
Merged
Conversation
ymote
force-pushed
the
deps/pdfcraft-upstream
branch
from
October 11, 2026 19:41
0a82c78 to
0c7c661
Compare
ymote
marked this pull request as ready for review
October 11, 2026 19:41
Moves the pdfcraft engine and its patched PDF stack from 615ff308 to 51f09eea: ymote/pdfcraft's merge of storytold/pdfcraft main (f22b5d42, 318 commits, ymote/pdfcraft#2) plus the fork's 4 MiB cap on the total of decoded page-label prefixes (ymote/pdfcraft#3), which upstream's code had dropped. All ten pdfcraft pins in the root Cargo.toml move, #501's pdfcraft-edit included. - The lock pins hayro-jbig2 to the engine's hardened copy. Its patch had been unused: crates.io's 0.3.1 outranked the vendored 0.3.0, so JBIG2 images were decoded without the engine's bounds on bitmap and dictionary pixels and on decoding steps that never advance. That also drops second copies of fearless_simd and hayro-ccitt. tests/skill.rs now fails if any of the five patches goes unused or isn't at the engine's revision. - vectorcraft moves to 2cd3a1ca (ymote/vectorcraft#1), whose PDF import takes the warning the engine's hayro-interpret adds (ContentTruncated). The patch reaches vectorcraft-pdf too, which otherwise stops compiling. Only the vector skill's revision lines change. - The pdf skill is regenerated: twelve new engine commands, each classified from its implementation in skill/safety-rules.json, and fill_sign_add is file now (its new `path` reads an image signature). ADR 0013's count of generated ids follows (4,569). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
fill_sign_add now reads an image signature from the file its `path` names. pdf.fill_sign builds the command's arguments itself, and args::only refuses `path`, `format` and `language` before any engine work. doc_tests::fill_sign_never_reads_a_file proves both sides: the engine places the image when called directly, while through the service every kind refuses those keys and the document stays untouched. review.rs's safety notes say fill_sign_add is file, and why it still runs as a plain document edit. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ymote
force-pushed
the
deps/pdfcraft-upstream
branch
from
October 11, 2026 19:54
0c7c661 to
0533955
Compare
Contributor
Author
|
Local CI passed on 0533955 ( GitHub would run for this PR: desktop.yml, phone.yml, apps.yml. Merged on this local pass (macOS runner queue); GitHub CI runs on the merge commit on main.
Skipped (these did NOT pass; (!) marks a skip that blocks tools/ci-local-merge.sh):
Notes:
Native GitHub acceptance passed on the same head: embedded-browser.yml. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
The pdfcraft engine (ADR 0013) was 318 commits behind upstream. Upstream's robustness work covers CMap parsing, JBIG2 dictionaries, decompression bombs, mesh shadings, dash patterns, PDF functions, image resampling, lopdf object streams, hayro nesting, JavaScript
util.printf, and content past 256 MiB. This PR brings that work in, as its own change. Font bundling and Chinese editing are out of scope.What
pdfcraft pins. All ten pdfcraft pins in the root
Cargo.tomlmove to ymote/pdfcraft 51f09eea. That includes #501'spdfcraft-editand the[patch.crates-io]block for the engine's PDF stack (hayro,hayro-interpret,hayro-jbig2,hayro-syntax,lopdf). The revision is two fork merges:mainat f22b5d42, keeping history. Upstream already has the fork's own two fixes, the comment dates and the page-label bounds.vectorcraft pins. The four vectorcraft pins move to ymote/vectorcraft 2cd3a1ca (ymote/vectorcraft#1). Here is why:
hayro-interpret, patched in for the whole workspace, has a thirdInterpreterWarning,ContentTruncated: page content cut at its safety budget.vectorcraft-pdfmatched the two crates.io variants exhaustively, so the shell withcraft-enginesno longer compiled (E0004).hayro-write, the other users of the patched stack, compile unchanged.The engine's hardened JBIG2 decoder is now the one built. On main,
Cargo.locklists thehayro-jbig2patch under[[patch.unused]]. Here is why:hayro-syntaxasks for^0.3.0.The fix and its guard:
hayro-jbig2to the patch (cargo update -p hayro-jbig2@0.3.1 --precise 0.3.0). That also drops second copies offearless_simdandhayro-ccitt.tests/skill.rsthe_engines_hardened_pdf_stack_is_the_one_builtfails if any of the five patches goes unused or isn't at the engine's revision.The page-label bound: looser, then restored.
a_hostile_page_label_cannot_kill_the_processpasses on every revision.Cargo.lock (1,875 → 1,882 packages):
pdfcraft-geomandpdfcraft-platform, and seven crates.io crates for pdfcraft-sign's new signature algorithms (sha3,keccak,sponge-cursor,ripemd,p521,bp256,bp384);New engine commands and their classes
Each class was read from the command's implementation in
apps/pdf/host-service/skill/safety-rules.json, and the skill is regenerated.command_run,command_batchcommand_runcalls the tool behind any registry command id (79 tools, among themdoc_open,doc_save,sign_document,js_runandaction_run) with the caller'sparams.command_batchruns up to 1,000 of them.printer_options/etc/cups/ppdand spawnslpoptions.doc_create_multipleout, or one PDF per file intoout_dir.fill_sign_addpath, it reads an image signature (PNG or JPEG, at most 4 MiB and 4 MP) from a file.bookmark_from_structurecomment_image_previewdoc_inspectdoc_infofor one or every open document.fill_sign_date_formatobject_list,object_movepage_enhance_camerarender_previewThe 144 commands: safe 90, file 33, code 14, device 3, host 4.
doc_save's rule now nameswrite_atomic's new staging file,.<name>.<16 hex>.pdfcraft-tmp. It is created exclusively, so a planted file or link at that name is never written through. ADR 0013's count of generated ids is now 4,569 (EN and zh-CN).fill_sign_addand the pdf service.pdf.fill_signstill calls it with reviewed arguments only.{page, type, at}, plustextfor text and initials.kindis neversignature.args::onlyrefusespath,format,languageand any other key before engine work.doc_tests::fill_sign_never_reads_a_file: the engine places an image frompathwhen called directly; throughpdf.fill_signevery kind refuses those keys, and the document is untouched.review.rs's safety notes sayfill_sign_addisfile, and why no file is read.What PDF Tools or the pdf service could notice
PDF Tools, end to end on the new engine. I ran it on the build host's headless weston, with the recipe in
apps/pdftools/tests/evidence/linux-20261011/README.md. The build wascargo build --locked -p octosense --no-default-features --features app-hub,craft-engines, at the runtime's 64 ms script budget. Neither shell log has a script error, an overrun or a panic.ui.py --only shell, light then dark: passed.The
--edit-sampleEdit run, light and dark, then Apply anyway and Apply at once: passed. It repeats the steps ofedit-20261011.No visible change. Every frame matches main's evidence pixel for pixel once cut to the app's area:
linux-20261011, drawn with pdfcraft d801407;edit-20261011, drawn with 615ff308.The only differences, neither from the engine:
font_label) afterlinux-20261011was taken.Edit said the same, word for word, as on 615ff308 in all four states PDF Tools: honest Edit on real-world PDFs (pdf.edit_check, plain refusals, a browser-printed test page) #501 recorded (the title piece and the Chinese piece, light and dark). That covers the five-pieces note, "Unnamed font · 27.8 pt", the Helvetica and room warnings, and the Chinese refusal.
Text: word gaps follow position on the line (Text extraction: word gaps follow position on the line, not drawing order (#1062) storytold/pdfcraft#1074). Text turned at an angle reads along its own baseline (M2: text turned at any angle reads as lines along its own baseline storytold/pdfcraft#735).
pdf.text,pdf.linesandpdf.findcan differ slightly on such files.Edit: a line split across content-stream pieces can be edited (Edit text: lines split across content stream pieces are listed and edited (fixes #155) storytold/pdfcraft#628).
Comments: a reply to a reply is listed (fix(comments): keep a reply to a reply in the comment listing (#806) storytold/pdfcraft#839).
Forms:
/Optexport values (Forms: radio groups and check boxes accept their /Opt export values storytold/pdfcraft#532).Merge: a page repeated in one selection gets its own annotations (Extract/Combine: a page repeated in one selection gets its own annotations (#818) storytold/pdfcraft#852).
Fill & Sign: the date is unchanged (
m/d/yyyy). Typed signatures stay upright on rotated pages (Typed and drawn signatures stay upright on rotated pages (fixes #299) storytold/pdfcraft#562).JBIG2: a hostile image is refused instead of decoded without bounds.
Page labels: a tree whose decoded prefixes pass 4 MiB shows physical page numbers with one warning, as before the sync.
Not affected: no existing pdf-service test needed a change. PDF Tools: honest Edit on real-world PDFs (pdf.edit_check, plain refusals, a browser-printed test page) #501's
edit_checkand refusal tests pass unchanged; they check exact fonts, boxes, piece counts and refusal words.Tests
On the Linux build host, Rust 1.99.0, on main cf06ac5 plus this branch. The tested tree's 12 changed files are byte for byte this head's.
OCTOSENSE_SKILL_REGEN=1 cargo test --locked -p octosense-pdf-service --test skillcargo test --locked -p octosense-pdf-servicecargo test --locked -p octosense-engine-areacargo clippy --locked -p octosense-pdf-service --all-targets -- -D warningsOCTOSENSE_SKILL_REGEN=1 cargo test --locked -p octosense-vector-service --test skillcargo test --locked -p octosense-vector-servicecargo clippy --locked -p octosense-vector-service --all-targets -- -D warningscargo test --locked -p octosense-design-servicephone/:cargo test --locked --features mobile-apps,craft-engines -p octosense-shell host_toolsevery_granted_engine_tool_answers_within_its_declared_resultcargo check --locked -p octosensecargo build --locked -p octosense --no-default-features --features app-hub,craft-enginesThe pdf-service run includes these tests:
a_printed_title_reads_as_pieces_in_subset_fonts,an_edit_check_says_when_the_font_or_the_room_changes,an_edit_check_foretells_the_edit,an_edit_the_engine_refuses_is_refused_in_plain_wordsandan_edit_check_on_a_plain_pdf_finds_nothing_to_say;a_hostile_comment_date_is_read_safely,a_comment_date_cut_inside_a_character_still_opensanda_hostile_page_label_cannot_kill_the_process;a_forms_own_scripts_never_run,work_goes_on_after_each_saveandfill_sign_never_reads_a_file.On the Mac, these pass:
python3 tools/setup.py --check --cargo;python3 tools/native_apps.py --check;bash tools/check-shell-graph.sh -p octosense, and fromphone/,bash ../tools/check-shell-graph.sh -p octosense-home.Not run:
rom paths: this PR touches no
rom/,phone/android/,phone/resources/android/,phone/tests/ortools/kernel-artifact.pypath, so rom.yml doesn't run.🤖 Generated with Claude Code