From dd47c2baa28aa83926a24691e2f7610f20a1e182 Mon Sep 17 00:00:00 2001 From: Johannes Altmanninger Date: Tue, 7 Oct 2025 18:52:38 +0200 Subject: [PATCH] Sanitize cursor position report on kitty click_events This is easy to trigger by having a background process do "echo" to move the terminal cursor to the next line, and then clicking anywhere. Fixes #11905 --- src/reader.rs | 2 +- src/screen.rs | 22 ++++++++++++++++++++-- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/reader.rs b/src/reader.rs index b2eb71a5e..cc7319c6d 100644 --- a/src/reader.rs +++ b/src/reader.rs @@ -1587,7 +1587,7 @@ pub fn mouse_left_click(&mut self, cursor: ViewportPosition, click_position: Vie self.pager.selected_completion_idx = Some(idx); self.pager_selection_changed(); } - _ => {} + CharOffset::Pager(_) | CharOffset::None => {} } } } diff --git a/src/screen.rs b/src/screen.rs index 6cb992f89..95bfda9dc 100644 --- a/src/screen.rs +++ b/src/screen.rs @@ -629,8 +629,26 @@ pub fn offset_in_cmdline_given_cursor( 0 }); let y = y.min(self.actual.line_count() - 1); - let viewport_prompt_x = viewport_cursor.x - self.actual.cursor.x; - let x = viewport_position.x - viewport_prompt_x; + let Some(viewport_prompt_x) = viewport_cursor.x.checked_sub(self.actual.cursor.x) else { + FLOGF!( + reader, + "Actual cursor x=%d exceeds reported cursor x=%d, \ + was the cursor moved by printing to the TTY?", + self.actual.cursor.x, + viewport_cursor.x + ); + return CharOffset::None; + }; + let Some(x) = viewport_position.x.checked_sub(viewport_prompt_x) else { + FLOGF!( + reader, + "Computed prompt x=%d exceeds mouse click x=%d, \ + was the cursor moved by printing to the TTY?", + viewport_prompt_x, + viewport_position.x + ); + return CharOffset::None; + }; let line = self.actual.line(y); let x = x.max(line.indentation); let offset = line