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
This commit is contained in:
Johannes Altmanninger
2025-10-07 18:52:38 +02:00
parent 15065255e9
commit dd47c2baa2
2 changed files with 21 additions and 3 deletions

View File

@@ -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.selected_completion_idx = Some(idx);
self.pager_selection_changed(); self.pager_selection_changed();
} }
_ => {} CharOffset::Pager(_) | CharOffset::None => {}
} }
} }
} }

View File

@@ -629,8 +629,26 @@ pub fn offset_in_cmdline_given_cursor(
0 0
}); });
let y = y.min(self.actual.line_count() - 1); let y = y.min(self.actual.line_count() - 1);
let viewport_prompt_x = viewport_cursor.x - self.actual.cursor.x; let Some(viewport_prompt_x) = viewport_cursor.x.checked_sub(self.actual.cursor.x) else {
let x = viewport_position.x - viewport_prompt_x; 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 line = self.actual.line(y);
let x = x.max(line.indentation); let x = x.max(line.indentation);
let offset = line let offset = line