From bccc568345f4029bc5d33d3cb1c6923c3c0cf8bb Mon Sep 17 00:00:00 2001 From: Takaranoao Date: Sun, 1 Mar 2026 04:55:06 -0800 Subject: [PATCH] fix(macOS): clamp IME selected_range to prevent substringToIndex crash macOS native Pinyin IME can send a selected_range that exceeds the marked text string length (e.g. index 8 for a 6-character string). This caused an NSRangeException in substringToIndex:, crashing the application with SIGABRT. Clamp both location and end to the string's UTF-16 length before calling substringToIndex. --- src/changelog/unreleased.md | 1 + src/platform_impl/macos/view.rs | 10 ++++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/changelog/unreleased.md b/src/changelog/unreleased.md index 7cfbe9145..6dc9fe489 100644 --- a/src/changelog/unreleased.md +++ b/src/changelog/unreleased.md @@ -45,3 +45,4 @@ changelog entry. - On macOS, fixed crash when dragging non-file content onto window. - On X11, fix `set_hittest` not working on some window managers. - On X11, fix debug mode overflow panic in `set_timestamp`. +- On macOS, fix crash in `set_marked_text` when native Pinyin IME sends out-of-bounds `selected_range`. diff --git a/src/platform_impl/macos/view.rs b/src/platform_impl/macos/view.rs index d2a9948fc..c7ca5bc6e 100644 --- a/src/platform_impl/macos/view.rs +++ b/src/platform_impl/macos/view.rs @@ -316,9 +316,15 @@ declare_class!( // sending a `None` cursor range. None } else { + // Clamp to string length to avoid NSRangeException from out-of-bounds + // indices sent by macOS IME (e.g. native Pinyin, see + // https://github.com/alacritty/alacritty/issues/8791). + let len = string.length(); + let location = selected_range.location.min(len); + let end = selected_range.end().min(len); // Convert the selected range from UTF-16 indices to UTF-8 indices. - let sub_string_a = unsafe { string.substringToIndex(selected_range.location) }; - let sub_string_b = unsafe { string.substringToIndex(selected_range.end()) }; + let sub_string_a = unsafe { string.substringToIndex(location) }; + let sub_string_b = unsafe { string.substringToIndex(end) }; let lowerbound_utf8 = sub_string_a.len(); let upperbound_utf8 = sub_string_b.len(); Some((lowerbound_utf8, upperbound_utf8))