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",
"project",
"rand 0.8.5",
"regex",
"schemars",
"search",
"serde",

View file

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

View file

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