From 01d72aa7d6de1117420c3cad14021f03c8a92a90 Mon Sep 17 00:00:00 2001 From: Anthony Eid <56899983+Anthony-Eid@users.noreply.github.com> Date: Fri, 23 Jan 2026 12:30:11 -0500 Subject: [PATCH] editor: Fix panics that could occur when content mask had negative bounds (#47327) Closes #47157 This panic happened because the editor was using `window.content_mask` to get the visible bounds, which had a negative value for its height in some cases. This happened for three reasons: 1. `Bounds::from_corners` returns a negative size if callers pass in corners where `bottom_right < top_left`. I originally wanted to add error checking to this function but didn't, because it might be better to move the error checking higher up. For now I'm going to push a fix and figure out a better solution later 2. `Bounds::intersect` could return negative-sized bounds when the two bounds didn't overlap, instead of returning a zero sized bounds. 3. `Style::paint` sometimes passed invalid corner values to `Bounds::from_corners` (where the computed bottom-right was above/left of the top-left). Release Notes: - editor: Fix a crash that could happen when editor visible line height is zero --------- Co-authored-by: Zed Zippy <234243425+zed-zippy[bot]@users.noreply.github.com> --- crates/gpui/src/geometry.rs | 5 ++++- crates/gpui/src/style.rs | 16 ++++++++++++---- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/crates/gpui/src/geometry.rs b/crates/gpui/src/geometry.rs index fc735ba5e0e7e719ed12b6b1b168ec3ee49e22bb..6d9a4fe281576a02aef9caaf7b91d5e28445e2c0 100644 --- a/crates/gpui/src/geometry.rs +++ b/crates/gpui/src/geometry.rs @@ -1112,7 +1112,10 @@ impl + Sub + Clone + Debug + Defa /// ``` pub fn intersect(&self, other: &Self) -> Self { let upper_left = self.origin.max(&other.origin); - let bottom_right = self.bottom_right().min(&other.bottom_right()); + let bottom_right = self + .bottom_right() + .min(&other.bottom_right()) + .max(&upper_left); Self::from_corners(upper_left, bottom_right) } diff --git a/crates/gpui/src/style.rs b/crates/gpui/src/style.rs index 7481b8001e5752599b90625450d7adb0c66ea2ca..d1ab41ff30a7b9da3fb9748919b9f2afe87f8cf2 100644 --- a/crates/gpui/src/style.rs +++ b/crates/gpui/src/style.rs @@ -666,23 +666,31 @@ impl Style { let border_widths = self.border_widths.to_pixels(rem_size); let max_border_width = border_widths.max(); let max_corner_radius = corner_radii.max(); + let zero_size = Size { + width: Pixels::ZERO, + height: Pixels::ZERO, + }; - let top_bounds = Bounds::from_corners( + let mut top_bounds = Bounds::from_corners( bounds.origin, bounds.top_right() + point(Pixels::ZERO, max_border_width.max(max_corner_radius)), ); - let bottom_bounds = Bounds::from_corners( + top_bounds.size = top_bounds.size.max(&zero_size); + let mut bottom_bounds = Bounds::from_corners( bounds.bottom_left() - point(Pixels::ZERO, max_border_width.max(max_corner_radius)), bounds.bottom_right(), ); - let left_bounds = Bounds::from_corners( + bottom_bounds.size = bottom_bounds.size.max(&zero_size); + let mut left_bounds = Bounds::from_corners( top_bounds.bottom_left(), bottom_bounds.origin + point(max_border_width, Pixels::ZERO), ); - let right_bounds = Bounds::from_corners( + left_bounds.size = left_bounds.size.max(&zero_size); + let mut right_bounds = Bounds::from_corners( top_bounds.bottom_right() - point(max_border_width, Pixels::ZERO), bottom_bounds.top_right(), ); + right_bounds.size = right_bounds.size.max(&zero_size); let mut background = self.border_color.unwrap_or_default(); background.a = 0.;