core: Acquire renderer state mutex before calling processLinks (#12463)
Holding the renderer state mutex is a documented precondition of `processLinks`, but `mouseButtonCallback` previously called the function without the mutex. This creates a race with the I/O thread's `processOutput`, which can prune scrollback pages while `processLinks` is reading them, resulting in a use-after-free segfault. See https://github.com/ghostty-org/ghostty/discussions/12409 (Linux: crash while selecting text).pull/12467/head57b5e1e250/src/Surface.zig (L4354-L4355)57b5e1e250/src/Surface.zig (L3822-L3824)995e4e375(os: open) changed the body of `processLinks` to be non-trivial and documented the precondition, but the lock was not held at the call site.
commit
e9ca0f8c9a
|
|
@ -3821,6 +3821,8 @@ pub fn mouseButtonCallback(
|
|||
// clicked link will swallow the event.
|
||||
if (self.mouse.over_link) {
|
||||
const pos = try self.rt_surface.getCursorPos();
|
||||
self.renderer_state.mutex.lock();
|
||||
defer self.renderer_state.mutex.unlock();
|
||||
if (self.processLinks(pos)) |processed| {
|
||||
if (processed) return true;
|
||||
} else |err| {
|
||||
|
|
|
|||
Loading…
Reference in New Issue