Remove another unwrap on regex compilation (#29984)

Follow up to #29979

Release Notes:

- Fixed a (hypothetical) panic in terminal search
This commit is contained in:
Conrad Irwin 2025-05-06 11:18:03 +01:00 committed by GitHub
parent 848c4f77a6
commit 4fdd14c3d8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 12 additions and 51 deletions

1
Cargo.lock generated
View file

@ -14746,6 +14746,7 @@ dependencies = [
"log", "log",
"project", "project",
"rand 0.8.5", "rand 0.8.5",
"regex",
"schemars", "schemars",
"search", "search",
"serde", "serde",

View file

@ -29,6 +29,7 @@ itertools.workspace = true
language.workspace = true language.workspace = true
log.workspace = true log.workspace = true
project.workspace = true project.workspace = true
regex.workspace = true
task.workspace = true task.workspace = true
schemars.workspace = true schemars.workspace = true
search.workspace = true search.workspace = true

View file

@ -57,10 +57,6 @@ use std::{
time::Duration, time::Duration,
}; };
const REGEX_SPECIAL_CHARS: &[char] = &[
'\\', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '^', '$',
];
const CURSOR_BLINK_INTERVAL: Duration = Duration::from_millis(500); const CURSOR_BLINK_INTERVAL: Duration = Duration::from_millis(500);
const GIT_DIFF_PATH_PREFIXES: &[&str] = &["a", "b"]; const GIT_DIFF_PATH_PREFIXES: &[&str] = &["a", "b"];
@ -1258,26 +1254,16 @@ fn possible_open_target(
}) })
} }
fn regex_to_literal(regex: &str) -> String { fn regex_search_for_query(query: &project::search::SearchQuery) -> Option<RegexSearch> {
regex let str = query.as_str();
.chars() if query.is_regex() {
.flat_map(|c| { if str == "." {
if REGEX_SPECIAL_CHARS.contains(&c) { return None;
vec!['\\', c] }
} else { RegexSearch::new(str).ok()
vec![c] } else {
} RegexSearch::new(&regex::escape(str)).ok()
})
.collect()
}
pub fn regex_search_for_query(query: &project::search::SearchQuery) -> Option<RegexSearch> {
let query = query.as_str();
if query == "." {
return None;
} }
let searcher = RegexSearch::new(query);
searcher.ok()
} }
impl TerminalView { impl TerminalView {
@ -1740,24 +1726,7 @@ impl SearchableItem for TerminalView {
_: &mut Window, _: &mut Window,
cx: &mut Context<Self>, cx: &mut Context<Self>,
) -> Task<Vec<Self::Match>> { ) -> Task<Vec<Self::Match>> {
let searcher = match &*query { if let Some(s) = regex_search_for_query(&query) {
SearchQuery::Text { .. } => regex_search_for_query(
&(SearchQuery::text(
regex_to_literal(query.as_str()),
query.whole_word(),
query.case_sensitive(),
query.include_ignored(),
query.files_to_include().clone(),
query.files_to_exclude().clone(),
false,
None,
)
.unwrap()),
),
SearchQuery::Regex { .. } => regex_search_for_query(&query),
};
if let Some(s) = searcher {
self.terminal() self.terminal()
.update(cx, |term, cx| term.find_matches(s, cx)) .update(cx, |term, cx| term.find_matches(s, cx))
} else { } else {
@ -2052,14 +2021,4 @@ mod tests {
project.update(cx, |project, cx| project.set_active_path(Some(p), cx)); project.update(cx, |project, cx| project.set_active_path(Some(p), cx));
}); });
} }
#[test]
fn escapes_only_special_characters() {
assert_eq!(regex_to_literal(r"test(\w)"), r"test\(\\w\)".to_string());
}
#[test]
fn empty_string_stays_empty() {
assert_eq!(regex_to_literal(""), "".to_string());
}
} }