summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Duerr <contact@christianduerr.com>2022-01-08 21:24:42 +0100
committerChristian Duerr <contact@christianduerr.com>2022-01-08 21:52:58 +0100
commitf1be68049bdb6b3028f74aca6e585fc1a8517623 (patch)
tree0c3942769853602d3186b34a3630fac8f0e856e2
parentd86e79f1ac47291672632c7c4edcded7a24293bb (diff)
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.md1
-rw-r--r--alacritty_terminal/src/term/search.rs28
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("\