Fix overflow panic when filling paths with extreme coordinates - #180
Open
StefanoD wants to merge 1 commit into
Open
Fix overflow panic when filling paths with extreme coordinates#180StefanoD wants to merge 1 commit into
StefanoD wants to merge 1 commit into
Conversation
When anti-aliased filling a path whose device-space vertical bounds lie far outside the clip, `start_y`/`stop_y` (the path bounds) were shifted up for supersampling with a plain `<<`. A large-negative bound then overflowed `i32` and wrapped into a large-positive value, escaping the subsequent clip clamp and breaking `walk_edges`' `last_y >= curr_y` invariant. Use a saturating shift so out-of-range bounds stay on the correct side and get clamped to the clip as intended. In-range bounds are unaffected. Originally reported against resvg: linebender/resvg#933 Reproduced with: <svg height="32" viewBox="0 0 8.4.9" width="32" x="w"> <g m=""><g><path d="m3 6h8v-158758583"/></g></g> </svg> Crash dump (debug build): thread 'main' panicked at tiny-skia/src/scan/path.rs:221:13: assertion failed: edges[curr_idx].last_y >= curr_y as i32 3: tiny_skia::scan::path::walk_edges 4: tiny_skia::scan::path::fill_path_impl 5: tiny_skia::scan::path_aa::fill_path_impl 6: tiny_skia::scan::path_aa::fill_path 7: tiny_skia::painter::<impl tiny_skia::pixmap::PixmapMut>::fill_path Crash dump (release build): thread 'main' panicked at tiny-skia/src/pipeline/mod.rs:181:31: range start index 15006310411 out of range for slice of length 1024 3: tiny_skia::pipeline::lowp::load_dst_tail 4: tiny_skia::pipeline::lowp::start 5: <tiny_skia::pipeline::blitter::RasterPipelineBlitter as tiny_skia::blitter::Blitter>::blit_anti_h 6: tiny_skia::scan::path_aa::SuperBlitter::flush 7: tiny_skia::scan::path_aa::fill_path_impl Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.
When anti-aliased filling a path whose device-space vertical bounds lie far outside the clip,
start_y/stop_y(the path bounds) were shifted up for supersampling with a plain<<. A large-negative bound then overflowedi32and wrapped into a large-positive value, escaping the subsequent clip clamp and breakingwalk_edges'last_y >= curr_yinvariant.Use a saturating shift so out-of-range bounds stay on the correct side and get clamped to the clip as intended. In-range bounds are unaffected.
Originally reported against resvg: linebender/resvg#933
Reproduced with:
Crash dump (debug build):
Crash dump (release build):
Generated by Claude
Note: I accidentally closed the original PR (#178) by deleting my fork, which auto-closed it. This reopens the same change — the branch and commits are unchanged.