M6.1: a panic inside the curve sweep (rare near-degenerate input) becomes PathOpsError::Degenerate instead of crashing (found by the randomized export test)

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
Brandon ThomasandClaude Opus 5.5 committed 2026-10-02 08:16:35 -04:00
1 parent bfa46e6cb4
commit 5a36fa1a9b
2 files changed
+8 -1

No files matched your search

+6 -1
View File
@@ -196,7 +196,12 @@ impl Tidy {
impl Arrangement {
pub(crate) fn new(paths: &[(BezPath, FillRule)]) -> Result<Self, PathOpsError> {
let eps = eps_for(paths.iter().map(|p| &p.0))?;
let top = Topology::<Multi>::from_paths(paths.iter().enumerate().map(|(i, (p, _))| (p, i)), eps).map_err(|_| PathOpsError::OpenPath)?;
// The sweep can panic on rare near-degenerate input; that must never take the app down,
// so it becomes an error (callers fall back to leaving the art unchanged).
let sweep = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
Topology::<Multi>::from_paths(paths.iter().enumerate().map(|(i, (p, _))| (p, i)), eps)
}));
let top = sweep.map_err(|_| PathOpsError::Degenerate)?.map_err(|_| PathOpsError::OpenPath)?;
let tidy = Tidy::keeping(DEFAULT_PRECISION, paths.iter().map(|p| &p.0));
Ok(Self { top, rules: paths.iter().map(|p| p.1).collect(), tidy })
}
+2
View File
@@ -26,4 +26,6 @@ pub enum PathOpsError {
NonFinite,
#[error("input path could not be closed")]
OpenPath,
#[error("the shapes are too degenerate to combine")]
Degenerate,
}