From e35e5ad14fce8456afdd89f2b392b9924bb27471 Mon Sep 17 00:00:00 2001 From: Christian Duerr Date: Sun, 17 Sep 2023 11:04:05 +0200 Subject: Fix regex memory usage This fixes an issue where regexes with a large number of possible states would consume excessive memory, since the entire DFA was compiled ahead of time. To solve this, the DFA is now built at runtime using `regex-automata`'s hybrid DFA. There are however still some checks performed ahead of time, causing errors with obscenely large regexes (`[0-9A-Za-z]{999999999}`), which shouldn't cause any issues. A regex which is large, but not large enough to fail the NFA construction (like `[0-9A-Za-z]{999999}`) will cause a long search of the entire grid, but will complete and show the match. Closes #7097. --- alacritty/src/config/ui_config.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'alacritty/src/config/ui_config.rs') diff --git a/alacritty/src/config/ui_config.rs b/alacritty/src/config/ui_config.rs index eb64f5b8..15423da5 100644 --- a/alacritty/src/config/ui_config.rs +++ b/alacritty/src/config/ui_config.rs @@ -485,7 +485,7 @@ impl LazyRegex { /// Execute a function with the compiled regex DFAs as parameter. pub fn with_compiled(&self, f: F) -> Option where - F: FnMut(&RegexSearch) -> T, + F: FnMut(&mut RegexSearch) -> T, { self.0.borrow_mut().compiled().map(f) } @@ -514,7 +514,7 @@ impl LazyRegexVariant { /// /// If the regex is not already compiled, this will compile the DFAs and store them for future /// access. - fn compiled(&mut self) -> Option<&RegexSearch> { + fn compiled(&mut self) -> Option<&mut RegexSearch> { // Check if the regex has already been compiled. let regex = match self { Self::Compiled(regex_search) => return Some(regex_search), @@ -578,8 +578,8 @@ mod tests { "ftp://ftp.example.org", ] { let term = mock_term(regular_url); - let regex = RegexSearch::new(URL_REGEX).unwrap(); - let matches = visible_regex_match_iter(&term, ®ex).collect::>(); + let mut regex = RegexSearch::new(URL_REGEX).unwrap(); + let matches = visible_regex_match_iter(&term, &mut regex).collect::>(); assert_eq!( matches.len(), 1, @@ -599,8 +599,8 @@ mod tests { "mailto:", ] { let term = mock_term(url_like); - let regex = RegexSearch::new(URL_REGEX).unwrap(); - let matches = visible_regex_match_iter(&term, ®ex).collect::>(); + let mut regex = RegexSearch::new(URL_REGEX).unwrap(); + let matches = visible_regex_match_iter(&term, &mut regex).collect::>(); assert!( matches.is_empty(), "Should not match url in string {url_like}, but instead got: {matches:?}" -- cgit