diff options
author | Christian Duerr <contact@christianduerr.com> | 2020-07-17 21:12:11 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-07-17 21:12:11 +0000 |
commit | 411318e6a5aaa72a9e35f489121546d84da093a2 (patch) | |
tree | 1cffe8df6374950a3433d2fc03bc78a79ff047ee | |
parent | 82d2cb0be60580212157fa1c002cdad944c5c662 (diff) | |
download | alacritty-411318e6a5aaa72a9e35f489121546d84da093a2.tar.gz alacritty-411318e6a5aaa72a9e35f489121546d84da093a2.zip |
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.
-rw-r--r-- | alacritty/src/display.rs | 26 | ||||
-rw-r--r-- | alacritty/src/event.rs | 1 |
2 files changed, 17 insertions, 10 deletions
diff --git a/alacritty/src/display.rs b/alacritty/src/display.rs index d832ba0e..abbb3666 100644 --- a/alacritty/src/display.rs +++ b/alacritty/src/display.rs @@ -592,7 +592,7 @@ impl Display { self.draw_search(config, &size_info, message_bar_lines, &search_text); // 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, }; @@ -627,25 +627,31 @@ impl Display { search_label: &str, ) -> String { // 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() { - text.push(c); + formatted_regex.push(c); if c.width() == Some(2) { - text.push(' '); + formatted_regex.push(' '); } } // 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 label_len = search_label.len(); - let text_len = text.len(); - let truncate_len = min((text_len + label_len).saturating_sub(num_cols), text_len); - text = format!("{}{}", search_label, &text[truncate_len..]); + let regex_len = formatted_regex.len(); + let truncate_len = min((regex_len + label_len).saturating_sub(num_cols), regex_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. diff --git a/alacritty/src/event.rs b/alacritty/src/event.rs index c934c31a..9fff5260 100644 --- a/alacritty/src/event.rs +++ b/alacritty/src/event.rs @@ -601,6 +601,7 @@ impl<'a, N: Notify + 'a, T: EventListener> ActionContext<'a, N, T> { fn absolute_origin(&self) -> Point<usize> { let mut relative_origin = self.search_state.origin; 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); origin.line = (origin.line as isize + self.search_state.display_offset_delta) as usize; origin |