diff options
author | Christian Duerr <contact@christianduerr.com> | 2022-01-08 21:24:42 +0100 |
---|---|---|
committer | Christian Duerr <contact@christianduerr.com> | 2022-01-08 21:52:58 +0100 |
commit | f1be68049bdb6b3028f74aca6e585fc1a8517623 (patch) | |
tree | 0c3942769853602d3186b34a3630fac8f0e856e2 | |
parent | d86e79f1ac47291672632c7c4edcded7a24293bb (diff) | |
download | alacritty-f1be68049bdb6b3028f74aca6e585fc1a8517623.tar.gz alacritty-f1be68049bdb6b3028f74aca6e585fc1a8517623.zip |
Fix fullwidth char regex search infinite loop
This resolves an issue where the regex search could loop indefinitely
when the end point was defined in a location containing a fullwidth
character, thus skipping over the end before termination.
Fixes #5753.
-rw-r--r-- | CHANGELOG.md | 1 | ||||
-rw-r--r-- | alacritty_terminal/src/term/search.rs | 28 |
2 files changed, 28 insertions, 1 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index d3df994c..16743e1b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,6 +39,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Freeze when the vi cursor is on the scrollback and scrollback clear is invoked - Vi cursor on topmost of the display moving downward when scrolled into history with active output - Input lag on Wayland with Nvidia binary driver +- Crash when hovering the mouse over fullwidth characters ### Removed diff --git a/alacritty_terminal/src/term/search.rs b/alacritty_terminal/src/term/search.rs index 07403b67..e34fd1b4 100644 --- a/alacritty_terminal/src/term/search.rs +++ b/alacritty_terminal/src/term/search.rs @@ -205,6 +205,7 @@ impl<T> Term<T> { let mut state = dfa.start_state(); let mut last_wrapped = false; let mut regex_match = None; + let mut done = false; let mut cell = iter.cell(); self.skip_fullwidth(&mut iter, &mut cell, direction); @@ -239,7 +240,7 @@ impl<T> Term<T> { } // Stop once we've reached the target point. - if point == end { + if point == end || done { break; } @@ -254,7 +255,12 @@ impl<T> Term<T> { iter.cell() }, }; + + // Check for completion before potentially skipping over fullwidth characters. + done = iter.point() == end; + self.skip_fullwidth(&mut iter, &mut cell, direction); + let wrapped = cell.flags.contains(Flags::WRAPLINE); c = cell.c; @@ -701,6 +707,26 @@ mod tests { } #[test] + fn end_on_fullwidth() { + let term = mock_term("jarr🦇"); + + let start = Point::new(Line(0), Column(0)); + let end = Point::new(Line(0), Column(4)); + + // Ensure ending without a match doesn't loop indefinitely. + let dfas = RegexSearch::new("x").unwrap(); + assert_eq!(term.regex_search_right(&dfas, start, end), None); + + let dfas = RegexSearch::new("x").unwrap(); + let match_end = Point::new(Line(0), Column(5)); + assert_eq!(term.regex_search_right(&dfas, start, match_end), None); + + // Ensure match is captured when only partially inside range. + let dfas = RegexSearch::new("jarr🦇").unwrap(); + assert_eq!(term.regex_search_right(&dfas, start, end), Some(start..=match_end)); + } + + #[test] fn wrapping() { #[rustfmt::skip] let term = mock_term("\ |