Keep crop finite when crop.set gets a huge rect

Found while testing crates/geom/src/crop.rs:59 (CropGeometry::constrained, via crates/engine/src/cmd/develop.rs:524 crop.set)

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
NetterSilverandClaude Haiku 5.5 committed 2026-10-15 00:44:54 +02:00
1 parent 3b4279fc24
commit 3080f71680
2 files changed
+31 -1

No files matched your search

+11
View File
@@ -424,6 +424,17 @@ fn degenerate_crops_render_with_spots_and_masks() {
}
}
/// `crop.set` with a huge rect shrank it by a scale of 0 (`inf * 0`) and stored a NaN crop.
#[test]
fn crop_set_huge_rect_stays_finite() {
for rect in [[0.0, 0.0, 1e308, 1e308], [-1e308, -1e308, 1e308, 1e308]] {
let mut s = demo();
let _ = s.execute("crop.set", &json!({"rect": rect}));
let r = active_dev(&s).crop.geometry.rect;
assert!([r.x0, r.y0, r.x1, r.y1].iter().all(|v| v.is_finite() && (-1e-6..=1.0 + 1e-6).contains(v)), "{rect:?}: {r:?}");
}
}
/// `mask.move` with a delta near `i64::MAX` overflowed `index + delta` (a panic wherever overflow
/// checks are on); extreme deltas and indices now move the mask to the bottom or the top.
#[test]
+20 -1
View File
@@ -77,7 +77,14 @@ impl CropGeometry {
let s = max_inscribed_scale(w, h, self.angle, r.width(), r.height());
let nr = Rect::from_center(c, r.width() * s, r.height() * s);
let _ = best;
CropGeometry { rect: nr.scale(1.0 / w, 1.0 / h), angle: self.angle }
let out = CropGeometry { rect: nr.scale(1.0 / w, 1.0 / h), angle: self.angle };
if [out.rect.x0, out.rect.y0, out.rect.x1, out.rect.y1].iter().all(|v| v.is_finite()) {
return out;
}
// A rect too large for pixel maths (`inf * 0` above): the largest crop of its aspect that
// fits, else of the image's own.
let aspect = Some(self.rect.width() / self.rect.height() * (w / h)).filter(|a| a.is_finite() && *a > 0.0);
crop_fit_angle(w, h, self.angle, aspect)
}
/// This crop turned to `angle_deg` on a `w × h` image: kept as it is when it still fits inside
@@ -211,4 +218,16 @@ mod tests {
let p = t.apply(Point::new(0.0, 0.0));
assert!((p.x - 25.0).abs() < 1e-9 && (p.y - 25.0).abs() < 1e-9);
}
#[test]
fn constrained_huge_rect_is_finite_and_inside() {
for rect in [Rect::new(0.0, 0.0, 1e308, 1e308), Rect::new(-1e308, -1e308, 1e308, 1e308), Rect::new(0.0, 0.0, 1e308, 0.5)] {
for angle in [0.0, 30.0] {
let c = CropGeometry { rect, angle }.constrained(400.0, 300.0);
let r = c.rect;
assert!([r.x0, r.y0, r.x1, r.y1].iter().all(|v| v.is_finite()), "{rect:?} {angle}: {r:?}");
assert!(c.is_within_image(400.0, 300.0), "{rect:?} {angle}: {r:?}");
}
}
}
}