1
0
Fork 0
mirror of https://github.com/alacritty/alacritty.git synced 2024-11-25 14:05:41 -05:00

Fix crashes during search

This fixes two crashes related to search. The first crash was due to
variable shadowing computing the incorrect length of a search as soon as
it was started, causing an overflow after attempting a subtraction.
Since overflows are only debug mode checks, in release this would lead
to an IME positioned far, far beyond the window's boundaries (likely
offscreen).

The other bug was that the search was always started from the last
column in reverse search without vi mode, but after shrinking the
terminal width that origin point is no longer a valid part of the grid.
As a result it would cause an index out of bounds. The line was already
clamped to the grid, but now the same is also done for the column.

Fixes #3987.
This commit is contained in:
Christian Duerr 2020-07-17 21:12:11 +00:00 committed by GitHub
parent 82d2cb0be6
commit 411318e6a5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 17 additions and 10 deletions

View file

@ -592,7 +592,7 @@ impl Display {
self.draw_search(config, &size_info, message_bar_lines, &search_text); self.draw_search(config, &size_info, message_bar_lines, &search_text);
// Compute IME position. // Compute IME position.
Point::new(size_info.lines() - 1, Column(regex.len() - 1)) Point::new(size_info.lines() - 1, Column(search_text.len() - 1))
}, },
None => cursor_point, None => cursor_point,
}; };
@ -627,25 +627,31 @@ impl Display {
search_label: &str, search_label: &str,
) -> String { ) -> String {
// Add spacers for wide chars. // Add spacers for wide chars.
let mut text = String::with_capacity(search_regex.len()); let mut formatted_regex = String::with_capacity(search_regex.len());
for c in search_regex.chars() { for c in search_regex.chars() {
text.push(c); formatted_regex.push(c);
if c.width() == Some(2) { if c.width() == Some(2) {
text.push(' '); formatted_regex.push(' ');
} }
} }
// Add cursor to show whitespace. // Add cursor to show whitespace.
text.push('_'); formatted_regex.push('_');
// Add search to the beginning of the search text. // Truncate beginning of the search regex if it exceeds the viewport width.
let num_cols = size_info.cols().0; let num_cols = size_info.cols().0;
let label_len = search_label.len(); let label_len = search_label.len();
let text_len = text.len(); let regex_len = formatted_regex.len();
let truncate_len = min((text_len + label_len).saturating_sub(num_cols), text_len); let truncate_len = min((regex_len + label_len).saturating_sub(num_cols), regex_len);
text = format!("{}{}", search_label, &text[truncate_len..]); let truncated_regex = &formatted_regex[truncate_len..];
text // Add search label to the beginning of the search regex.
let mut bar_text = format!("{}{}", search_label, truncated_regex);
// Make sure the label alone doesn't exceed the viewport width.
bar_text.truncate(num_cols);
bar_text
} }
/// Draw current search regex. /// Draw current search regex.

View file

@ -601,6 +601,7 @@ impl<'a, N: Notify + 'a, T: EventListener> ActionContext<'a, N, T> {
fn absolute_origin(&self) -> Point<usize> { fn absolute_origin(&self) -> Point<usize> {
let mut relative_origin = self.search_state.origin; let mut relative_origin = self.search_state.origin;
relative_origin.line = min(relative_origin.line, self.terminal.screen_lines() - 1); relative_origin.line = min(relative_origin.line, self.terminal.screen_lines() - 1);
relative_origin.col = min(relative_origin.col, self.terminal.cols() - 1);
let mut origin = self.terminal.visible_to_buffer(relative_origin); let mut origin = self.terminal.visible_to_buffer(relative_origin);
origin.line = (origin.line as isize + self.search_state.display_offset_delta) as usize; origin.line = (origin.line as isize + self.search_state.display_offset_delta) as usize;
origin origin