1
0
Fork 0
mirror of https://github.com/alacritty/alacritty.git synced 2024-11-11 13:51:01 -05:00

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.
This commit is contained in:
Christian Duerr 2022-01-08 21:24:42 +01:00 committed by GitHub
parent 5aa8046c7f
commit ed35d033ae
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 28 additions and 1 deletions

View file

@ -49,6 +49,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

View file

@ -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;
@ -700,6 +706,26 @@ mod tests {
assert_eq!(term.regex_search_left(&dfas, start, end), Some(end..=start));
}
#[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]