You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
DESIGN.md §6, I3. hayro 0.8.0 panics on some malformed input, for example on colour components that do not match their colour space (LaurenzV/hayro#1546). pylopdf contains every interpretation in catch_unwind and maps a panic to PdfError.
Goal
Malformed input yields errors from hayro, and catch_unwind stays in pyropdf only as a last defense that its tests never reach.
hayro-syntax 0.8.0 also panics, found while doing #22: ArrayIter::next (object/array.rs, the unwrap after read_with_context) and Dict::entries unwrap an element that the parser skipped but cannot read. Inputs that reach it through the public FromBytes:
[/AB#FG]: a name whose # is not followed by two hexadecimal digits;
[+ 1]: a lone +, which Number::skip accepts and Number::read refuses;
[<< /AB#FG /X >>]: a dictionary that Dict::skip accepts and Dict::read refuses.
hayro's main fixes both unwraps in LaurenzV/hayro#1501 ("Don't panic on unreadable values in dictionaries and arrays"), and LaurenzV/hayro#1568 keeps a # that is not an escape; neither is released yet. Until the adoption (#7, "Adopt released versions"), the store converts objects inside catch_unwind and maps a panic to a malformed-input error. Its test a_panic_in_hayro_syntax_is_a_malformed_input_error in crates/pyropdf-store/src/value/tests.rs changes with the adoption.
Upstream status, checked 2026-10-28 against LaurenzV/hayro main 8558a8a5:
Every hayro panic this issue names is fixed on main: #1501 (unreadable array and dict values), #1562 (colour components that do not match their colour space, the #1546 cases), and #1568 (a # that is not an escape). None is released yet: the latest tags are still hayro-interpret-v0.8.0 and its siblings. No local hayro patch is needed; this issue waits for a hayro release and its adoption (Engine work: hayro #7).
The remaining open case is vello_cpu#646, which pylopdf#338 tracks (it keeps contain_renderer_panics). That is a linebender repository, and pylopdf's records hold no minimal reproduction, so I have prepared no patch for it. A reproduction first needs the fuzz target this issue asks for.
That fuzz target is pyropdf work and could start now. It would fail on 0.8.0's known panics until the adoption, so its CI acceptance waits for the release.
Next action: when hayro 0.9 is released, adopt it, add the interpretation fuzz target, and record any vello_cpu panic it finds with a reproduction.
Added the interpret fuzz target: raster, SVG, content items, and text of the first four pages, of a whole file or of a content stream in a one-page template with varied resources. It keeps libFuzzer's panic hook, so any panic fails it, including the ones the store's catch_unwind catches. It is not in the CI matrix; fuzz.yml says it joins after the hayro adoption (Engine work: hayro #7).
hayro main (a543cdba): pyropdf-engine does not build against it (InterpreterSettings::render_annotations removed, begin_marked_content changed, SoftMask::id gone), which is Engine work: hayro #7's work. So I replayed the corpus (3,123 inputs) through hayro::render and hayro_svg::convert of main alone: the #1546 case no longer panics, and the only panic is three inputs with a huge /MediaBox, where hayro::render casts the size to u16 and vello_cpu panics. pyropdf does not call hayro::render.
Unknown panic found, pyropdf-reachable: vello_cpu 0.3.0 panics on rasters 65,409 to 65,532 pixels wide (span.rs:87) and on 65,533 to 65,535 wide or high (vello_commonutil.rs:237/238), and render::raster accepts up to 65,535. Minimal reproduction and follow-up in Refuse raster sizes that vello_cpu 0.3 panics on #392. The lines are still on linebender/vello main37f7119e; no upstream report exists, and publishing one needs the owner's approval.
Triage, 2026-11-03: hayro 0.9.0 (released 2026-11-02) contains the upstream fixes this issue waited on, so I replaced upstream and upstream:merged with adoption. pyropdf cannot adopt 0.9 yet: it drops OutlineGlyph::font_cache_key() and SoftMask::id(), which the engine reads. #584 tracks putting them back (LaurenzV/hayro#1734, awaiting review), so this issue is now blocked by #584. The 0.9 bump itself resumes on #18's branch claude/18-hayro-0.9-u32.
Next action: once a hayro release contains LaurenzV/hayro#1734 and the bump lands, adopt this issue's change.
Dependency triage, 2026-11-06: removed the obsolete blocked-by link to #584. PR #609 already merged the owner-approved hayro 0.9-based commit 394e4a0d37baf8af513f6ebda15f4bada85d6f23, and both the workspace and fuzz manifests use it. This issue's 0.9 capability is available now; #603 separately retains the #584 dependency for returning to published crates. This does not close #584 or waive any acceptance criterion here.
Next action: Enable and validate the existing interpretation fuzz target against the current dependency, and investigate any panic it finds.
No implementation claim is held by this triage. Recheck the live queue, claim a branch and complete the existing acceptance before closing.
Handoff on codex/19-interpret-fuzz-ci, PR #708, head 5f915ec1be17cfe410c15a84d14846a69ff66598. Enabled the existing panic-sensitive interpretation target; refreshed only fuzz lockfile local versions and documented the nine-job budget. The branch is pushed and clean.
All eight locked local checks passed (Python 7,398 passed, 705 skipped), as did native Windows interpretation-target cargo check --locked, actionlint 1.7.12, and cargo-audit 0.22.2 for both lockfiles. Seed generation produced 343 interpretation inputs.
CI run 42122505556 has completed successfully. Fuzz run 42122505562 has eight existing targets successful; interpretation job 127578212523 is confirmed in progress in the Fuzz step. This step includes compilation. Keep observing this run; do not restart merely because it is slow. No merge until this check succeeds and its log proves the configured fuzz run completed. Reviews/comments/threads were empty at inspection.
The implementation claim is released while this external job runs; the open PR keeps #19 out of the new-work queue. Next: inspect its result/artifacts, reclaim for any fix, then merge and verify main if acceptance succeeds. Independent #365 measurement can proceed in a fresh session while this run continues. No owner approval is pending.
Known-panic follow-up while PR #708's interpretation job runs: GitHub compare confirms hayro 0.9.0 contains the #1562 fix (0a4baaf99bcab9e93cfefd7eb712ee76161b496d). The width/tile overflow discovered by this target is guarded locally by #392/#406 (MAX_WIDTH = 65_408); vello#2040 is still open. Other live upstream reports are vello#2037 (2 GiB alpha scene) and vello#2005 (fuzz findings). The old vello_cpu#646 shorthand in pylopdf#338 still does not identify a resolvable matching report, so it is not claimed fixed.
A successful configured CI fuzz run meets this issue's bounded regression acceptance; it is not proof that every malformed input is panic-free. Keep the last-defense panic boundary and track any new finding with its reproduction. Current CI run 42122505556 has succeeded; interpretation job 127578212523 in Fuzz run 42122505562 is still confirmed running.
Merged #708 as 938b94d (branch codex/19-interpret-fuzz-ci). All 14 current-head checks passed; no unresolved review threads. The interpretation job in run 42122505562 loaded 343 seed files and completed 453 executions in 178 seconds without a panic (797 MiB RSS). Seed initialization exceeded -max_total_time=60, so this PR run establishes seed regression coverage, not additional mutation coverage; the weekly 15-minute configuration provides a longer exploration budget. The default libFuzzer panic hook remains intact.
Release adoption and remaining upstream panic reports are audited in #19 (comment). The last-defense panic boundary remains. Next: verify main CI for the merge; investigate any future fuzz crash without weakening the hook.
Post-merge verification: the issue is closed, no in-progress label remains, and main CI 42125740133 for 938b94d succeeded. Main Fuzz run 42125740283 is still running its interpretation job; all eight other fuzz jobs passed. Continue that existing run and investigate any failure. The next-work report was refreshed after merge.
Final post-merge verification for 938b94d5f9584c5c21a013265a3c8c4cfe0714b4: main CI 42125740133 and all nine jobs in Fuzz 42125740283 succeeded. Interpretation loaded 343 seed files and completed 456 executions in 185 seconds without a panic, at 784 MiB RSS. As on the PR, initialization consumed the short-run time budget; no claim of extra mutation coverage is made. The weekly 15-minute run retains the longer exploration budget. No further merge-validation work remains for #708.
Activity
yhay81 commentedon Oct 24, 2026
hayro-syntax 0.8.0 also panics, found while doing #22:
ArrayIter::next(object/array.rs, theunwrapafterread_with_context) andDict::entriesunwrap an element that the parser skipped but cannot read. Inputs that reach it through the publicFromBytes:[/AB#FG]: a name whose#is not followed by two hexadecimal digits;[+ 1]: a lone+, whichNumber::skipaccepts andNumber::readrefuses;[<< /AB#FG /X >>]: a dictionary thatDict::skipaccepts andDict::readrefuses.hayro's main fixes both unwraps in LaurenzV/hayro#1501 ("Don't panic on unreadable values in dictionaries and arrays"), and LaurenzV/hayro#1568 keeps a
#that is not an escape; neither is released yet. Until the adoption (#7, "Adopt released versions"), the store converts objects insidecatch_unwindand maps a panic to a malformed-input error. Its testa_panic_in_hayro_syntax_is_a_malformed_input_errorincrates/pyropdf-store/src/value/tests.rschanges with the adoption.yhay81 commentedon Oct 27, 2026
Upstream status, checked 2026-10-28 against LaurenzV/hayro main
8558a8a5:#that is not an escape). None is released yet: the latest tags are stillhayro-interpret-v0.8.0and its siblings. No local hayro patch is needed; this issue waits for a hayro release and its adoption (Engine work: hayro #7).contain_renderer_panics). That is a linebender repository, and pylopdf's records hold no minimal reproduction, so I have prepared no patch for it. A reproduction first needs the fuzz target this issue asks for.Next action: when hayro 0.9 is released, adopt it, add the interpretation fuzz target, and record any vello_cpu panic it finds with a reproduction.
yhay81 commentedon Oct 30, 2026
Claimed for the interpretation fuzz target in Scope: branch
claude/19-fuzz-interpret. The target's CI run stays off until the hayro 0.9 adoption (#7).yhay81 commentedon Oct 30, 2026
Handoff (branch
claude/19-fuzz-interpret, PR #391, awaiting owner review):interpretfuzz target: raster, SVG, content items, and text of the first four pages, of a whole file or of a content stream in a one-page template with varied resources. It keeps libFuzzer's panic hook, so any panic fails it, including the ones the store'scatch_unwindcatches. It is not in the CI matrix;fuzz.ymlsays it joins after the hayro adoption (Engine work: hayro #7).hayro-interpret-0.8.0/src/color/device_rgb.rs:8). Locally (macOS, ASan) 25 minutes and about 31,000 executions found no crash on hayro 0.8.0. Interpretation is slow (1–11 exec/s; whole real-world files take about 2 s each).main(a543cdba): pyropdf-engine does not build against it (InterpreterSettings::render_annotationsremoved,begin_marked_contentchanged,SoftMask::idgone), which is Engine work: hayro #7's work. So I replayed the corpus (3,123 inputs) throughhayro::renderandhayro_svg::convertofmainalone: the #1546 case no longer panics, and the only panic is three inputs with a huge/MediaBox, wherehayro::rendercasts the size tou16and vello_cpu panics. pyropdf does not callhayro::render.span.rs:87) and on 65,533 to 65,535 wide or high (vello_commonutil.rs:237/238), andrender::rasteraccepts up to 65,535. Minimal reproduction and follow-up in Refuse raster sizes that vello_cpu 0.3 panics on #392. The lines are still on linebender/vellomain37f7119e; no upstream report exists, and publishing one needs the owner's approval.vello_cpurepository. Whether it is the case of Refuse raster sizes that vello_cpu 0.3 panics on #392, Fuzzing: multiple panics, timeouts and OOMs linebender/vello#2005 (fuzzing panics), or vello_cpu: fill_path panics with "alpha_idx too large" once a scene holds 2 GiB of alphas linebender/vello#2037 (alpha_idx too large) needs the original source in pylopdf's records.Next action: after #7 adopts hayro 0.9, add
interpretto the matrix offuzz.ymland check this issue's acceptance; fix #392 in the meantime.Add an interpretation fuzz target that fails on any panic (#19) (#391)
yhay81 commentedon Nov 3, 2026
Triage, 2026-11-03: hayro 0.9.0 (released 2026-11-02) contains the upstream fixes this issue waited on, so I replaced
upstreamandupstream:mergedwithadoption. pyropdf cannot adopt 0.9 yet: it dropsOutlineGlyph::font_cache_key()andSoftMask::id(), which the engine reads. #584 tracks putting them back (LaurenzV/hayro#1734, awaiting review), so this issue is now blocked by #584. The 0.9 bump itself resumes on #18's branchclaude/18-hayro-0.9-u32.Next action: once a hayro release contains LaurenzV/hayro#1734 and the bump lands, adopt this issue's change.
yhay81 commentedon Nov 5, 2026
Dependency triage, 2026-11-06: removed the obsolete blocked-by link to #584. PR #609 already merged the owner-approved hayro 0.9-based commit
394e4a0d37baf8af513f6ebda15f4bada85d6f23, and both the workspace and fuzz manifests use it. This issue's 0.9 capability is available now; #603 separately retains the #584 dependency for returning to published crates. This does not close #584 or waive any acceptance criterion here.Next action: Enable and validate the existing interpretation fuzz target against the current dependency, and investigate any panic it finds.
No implementation claim is held by this triage. Recheck the live queue, claim a branch and complete the existing acceptance before closing.
yhay81 commentedon Nov 5, 2026
Handoff on
codex/19-interpret-fuzz-ci, PR #708, head5f915ec1be17cfe410c15a84d14846a69ff66598. Enabled the existing panic-sensitive interpretation target; refreshed only fuzz lockfile local versions and documented the nine-job budget. The branch is pushed and clean.All eight locked local checks passed (Python 7,398 passed, 705 skipped), as did native Windows interpretation-target
cargo check --locked, actionlint 1.7.12, and cargo-audit 0.22.2 for both lockfiles. Seed generation produced 343 interpretation inputs.CI run 42122505556 has completed successfully. Fuzz run 42122505562 has eight existing targets successful; interpretation job
127578212523is confirmed in progress in the Fuzz step. This step includes compilation. Keep observing this run; do not restart merely because it is slow. No merge until this check succeeds and its log proves the configured fuzz run completed. Reviews/comments/threads were empty at inspection.The implementation claim is released while this external job runs; the open PR keeps #19 out of the new-work queue. Next: inspect its result/artifacts, reclaim for any fix, then merge and verify main if acceptance succeeds. Independent #365 measurement can proceed in a fresh session while this run continues. No owner approval is pending.
yhay81 commentedon Nov 5, 2026
Known-panic follow-up while PR #708's interpretation job runs: GitHub compare confirms hayro 0.9.0 contains the #1562 fix (
0a4baaf99bcab9e93cfefd7eb712ee76161b496d). The width/tile overflow discovered by this target is guarded locally by #392/#406 (MAX_WIDTH = 65_408); vello#2040 is still open. Other live upstream reports are vello#2037 (2 GiB alpha scene) and vello#2005 (fuzz findings). The oldvello_cpu#646shorthand in pylopdf#338 still does not identify a resolvable matching report, so it is not claimed fixed.A successful configured CI fuzz run meets this issue's bounded regression acceptance; it is not proof that every malformed input is panic-free. Keep the last-defense panic boundary and track any new finding with its reproduction. Current CI run 42122505556 has succeeded; interpretation job 127578212523 in Fuzz run 42122505562 is still confirmed running.
yhay81 commentedon Nov 5, 2026
Merged #708 as 938b94d (branch
codex/19-interpret-fuzz-ci). All 14 current-head checks passed; no unresolved review threads. The interpretation job in run 42122505562 loaded 343 seed files and completed 453 executions in 178 seconds without a panic (797 MiB RSS). Seed initialization exceeded-max_total_time=60, so this PR run establishes seed regression coverage, not additional mutation coverage; the weekly 15-minute configuration provides a longer exploration budget. The default libFuzzer panic hook remains intact.Release adoption and remaining upstream panic reports are audited in #19 (comment). The last-defense panic boundary remains. Next: verify main CI for the merge; investigate any future fuzz crash without weakening the hook.
yhay81 commentedon Nov 5, 2026
Post-merge verification: the issue is closed, no in-progress label remains, and main CI 42125740133 for 938b94d succeeded. Main Fuzz run 42125740283 is still running its interpretation job; all eight other fuzz jobs passed. Continue that existing run and investigate any failure. The next-work report was refreshed after merge.
yhay81 commentedon Nov 5, 2026
Final post-merge verification for
938b94d5f9584c5c21a013265a3c8c4cfe0714b4: main CI 42125740133 and all nine jobs in Fuzz 42125740283 succeeded. Interpretation loaded 343 seed files and completed 456 executions in 185 seconds without a panic, at 784 MiB RSS. As on the PR, initialization consumed the short-run time budget; no claim of extra mutation coverage is made. The weekly 15-minute run retains the longer exploration budget. No further merge-validation work remains for #708.