mirror of
https://github.com/zed-industries/zed.git
synced 2024-11-07 20:39:04 +03:00
gpui: Handle null string pointer in window::insert_text
(#12446)
`[NSString UTF8String]` sometimes returns null (it's documented as such), and when it does, zed crashes in `window::insert_text`. I'm running into this sometimes when using alt-d to delete forward. It usually only happens with multiple cursors, but sometimes with a single cursor. It *might* only happen when using the "Unicode Hex Input" keyboard 'Input Source' (which I started using to avoid entering weird characters in zed when using emacs meta keybindings that I haven't defined in zed). When using the US English input source, alt-d always results in a call to `insert_text`. When using the Unicode Hex Input source it usually doesn't, but when it does `text.UTF8String()` returns null. `text` isn't null. `[text length]` returns 1. `[text characterAtIndex: 0]` seems to always return `56797` (an undefined utf-16 codepoint). Release Notes: - Fixed crash on mac when deleting with alt-d
This commit is contained in:
parent
344e5e1cf2
commit
be2df79d5c
@ -29,7 +29,10 @@ use cocoa::{
|
||||
};
|
||||
|
||||
use objc::runtime::{BOOL, NO, YES};
|
||||
use std::ops::Range;
|
||||
use std::{
|
||||
ffi::{c_char, CStr},
|
||||
ops::Range,
|
||||
};
|
||||
|
||||
pub(crate) use dispatcher::*;
|
||||
pub(crate) use display::*;
|
||||
@ -52,6 +55,21 @@ impl BoolExt for bool {
|
||||
}
|
||||
}
|
||||
|
||||
trait NSStringExt {
|
||||
unsafe fn to_str(&self) -> &str;
|
||||
}
|
||||
|
||||
impl NSStringExt for id {
|
||||
unsafe fn to_str(&self) -> &str {
|
||||
let cstr = self.UTF8String();
|
||||
if cstr.is_null() {
|
||||
""
|
||||
} else {
|
||||
CStr::from_ptr(cstr as *mut c_char).to_str().unwrap()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
struct NSRange {
|
||||
|
@ -1,12 +1,12 @@
|
||||
use crate::{
|
||||
point, px, KeyDownEvent, KeyUpEvent, Keystroke, Modifiers, ModifiersChangedEvent, MouseButton,
|
||||
MouseDownEvent, MouseExitEvent, MouseMoveEvent, MouseUpEvent, NavigationDirection, Pixels,
|
||||
PlatformInput, ScrollDelta, ScrollWheelEvent, TouchPhase,
|
||||
platform::mac::NSStringExt, point, px, KeyDownEvent, KeyUpEvent, Keystroke, Modifiers,
|
||||
ModifiersChangedEvent, MouseButton, MouseDownEvent, MouseExitEvent, MouseMoveEvent,
|
||||
MouseUpEvent, NavigationDirection, Pixels, PlatformInput, ScrollDelta, ScrollWheelEvent,
|
||||
TouchPhase,
|
||||
};
|
||||
use cocoa::{
|
||||
appkit::{NSEvent, NSEventModifierFlags, NSEventPhase, NSEventType},
|
||||
base::{id, YES},
|
||||
foundation::NSString as _,
|
||||
};
|
||||
use core_graphics::{
|
||||
event::{CGEvent, CGEventFlags, CGKeyCode},
|
||||
@ -15,7 +15,7 @@ use core_graphics::{
|
||||
use ctor::ctor;
|
||||
use metal::foreign_types::ForeignType as _;
|
||||
use objc::{class, msg_send, sel, sel_impl};
|
||||
use std::{borrow::Cow, ffi::CStr, mem, os::raw::c_char, ptr};
|
||||
use std::{borrow::Cow, mem, ptr};
|
||||
|
||||
const BACKSPACE_KEY: u16 = 0x7f;
|
||||
const SPACE_KEY: u16 = b' ' as u16;
|
||||
@ -243,11 +243,10 @@ impl PlatformInput {
|
||||
unsafe fn parse_keystroke(native_event: id) -> Keystroke {
|
||||
use cocoa::appkit::*;
|
||||
|
||||
let mut chars_ignoring_modifiers =
|
||||
CStr::from_ptr(native_event.charactersIgnoringModifiers().UTF8String() as *mut c_char)
|
||||
.to_str()
|
||||
.unwrap()
|
||||
.to_string();
|
||||
let mut chars_ignoring_modifiers = native_event
|
||||
.charactersIgnoringModifiers()
|
||||
.to_str()
|
||||
.to_string();
|
||||
let first_char = chars_ignoring_modifiers.chars().next().map(|ch| ch as u16);
|
||||
let modifiers = native_event.modifierFlags();
|
||||
|
||||
@ -351,9 +350,6 @@ fn chars_for_modified_key(code: CGKeyCode, cmd: bool, shift: bool) -> String {
|
||||
|
||||
unsafe {
|
||||
let event: id = msg_send![class!(NSEvent), eventWithCGEvent: &*event];
|
||||
CStr::from_ptr(event.characters().UTF8String())
|
||||
.to_str()
|
||||
.unwrap()
|
||||
.to_string()
|
||||
event.characters().to_str().to_string()
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
use super::{ns_string, renderer, MacDisplay, NSRange};
|
||||
use super::{ns_string, renderer, MacDisplay, NSRange, NSStringExt};
|
||||
use crate::{
|
||||
platform::PlatformInputHandler, point, px, size, AnyWindowHandle, Bounds, DevicePixels,
|
||||
DisplayLink, ExternalPaths, FileDropEvent, ForegroundExecutor, KeyDownEvent, Keystroke,
|
||||
@ -39,7 +39,6 @@ use std::{
|
||||
ffi::{c_void, CStr},
|
||||
mem,
|
||||
ops::Range,
|
||||
os::raw::c_char,
|
||||
path::PathBuf,
|
||||
ptr::{self, NonNull},
|
||||
rc::Rc,
|
||||
@ -1711,9 +1710,8 @@ extern "C" fn insert_text(this: &Object, _: Sel, text: id, replacement_range: NS
|
||||
} else {
|
||||
text
|
||||
};
|
||||
let text = CStr::from_ptr(text.UTF8String() as *mut c_char)
|
||||
.to_str()
|
||||
.unwrap();
|
||||
|
||||
let text = text.to_str();
|
||||
let replacement_range = replacement_range.to_range();
|
||||
send_to_input_handler(
|
||||
this,
|
||||
@ -1739,9 +1737,7 @@ extern "C" fn set_marked_text(
|
||||
};
|
||||
let selected_range = selected_range.to_range();
|
||||
let replacement_range = replacement_range.to_range();
|
||||
let text = CStr::from_ptr(text.UTF8String() as *mut c_char)
|
||||
.to_str()
|
||||
.unwrap();
|
||||
let text = text.to_str();
|
||||
|
||||
send_to_input_handler(
|
||||
this,
|
||||
|
Loading…
Reference in New Issue
Block a user