From 3ed6c68f3b3c25e35aab2a69433b68a316e5258c Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Thu, 15 Jan 2026 17:02:54 +0100 Subject: [PATCH] gpui: Fix utf8 slicing panic in `truncate_line` (#46914) Fixes https://github.com/zed-industries/zed/issues/46904 Release Notes: - Fixed a panic in the git panel when utf8 multibyte character filenames got truncated --- crates/gpui/src/text_system/line_wrapper.rs | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/crates/gpui/src/text_system/line_wrapper.rs b/crates/gpui/src/text_system/line_wrapper.rs index 623c886b6b5e4aad2cefe7736025425acb9c8032..c77fbf65fb2a07d158b6469fd75ecfa17b79ee47 100644 --- a/crates/gpui/src/text_system/line_wrapper.rs +++ b/crates/gpui/src/text_system/line_wrapper.rs @@ -201,9 +201,10 @@ impl LineWrapper { self.should_truncate_line(&line, truncate_width, truncation_affix, truncate_from) { let result = match truncate_from { - TruncateFrom::Start => { - SharedString::from(format!("{truncation_affix}{}", &line[truncate_ix + 1..])) - } + TruncateFrom::Start => SharedString::from(format!( + "{truncation_affix}{}", + &line[line.ceil_char_boundary(truncate_ix + 1)..] + )), TruncateFrom::End => { SharedString::from(format!("{}{truncation_affix}", &line[..truncate_ix])) } @@ -599,12 +600,19 @@ mod tests { "aa bbb cccc dddd......", "......", ); + perform_test( + &mut wrapper, + "aa bbb cccc 🦀🦀🦀🦀🦀 eeee ffff gggg", + "aa bbb cccc 🦀🦀🦀🦀…", + "…", + ); } #[test] fn test_truncate_line_start() { let mut wrapper = build_wrapper(); + #[track_caller] fn perform_test( wrapper: &mut LineWrapper, text: &'static str, @@ -642,6 +650,12 @@ mod tests { "......dddd eeee fff gg", "......", ); + perform_test( + &mut wrapper, + "aaaa bbbb cccc 🦀🦀🦀🦀🦀 eeee fff gg", + "…🦀🦀🦀🦀 eeee fff gg", + "…", + ); } #[test]