Skip to content

Commit

Permalink
fix: better handle escape chars in pattern bracket exprs (#281)
Browse files Browse the repository at this point in the history
  • Loading branch information
reubeno authored Nov 30, 2024
1 parent 48fc1ef commit a2db75f
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 30 deletions.
36 changes: 6 additions & 30 deletions brush-core/src/patterns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -297,25 +297,17 @@ impl Pattern {
current_pattern.push_str(s);
}
PatternPiece::Literal(s) => {
if !current_pattern.is_empty() {
let regex_piece = pattern_to_regex_str(
current_pattern.as_str(),
self.enable_extended_globbing,
)?;
regex_str.push_str(regex_piece.as_str());
current_pattern = String::new();
for c in s.chars() {
current_pattern.push('\\');
current_pattern.push(c);
}

regex_str.push_str(escape_for_regex(s).as_str());
}
}
}

if !current_pattern.is_empty() {
let regex_piece =
pattern_to_regex_str(current_pattern.as_str(), self.enable_extended_globbing)?;
regex_str.push_str(regex_piece.as_str());
}
let regex_piece =
pattern_to_regex_str(current_pattern.as_str(), self.enable_extended_globbing)?;
regex_str.push_str(regex_piece.as_str());

if strict_suffix_match {
regex_str.push('$');
Expand Down Expand Up @@ -361,26 +353,10 @@ fn requires_expansion(s: &str) -> bool {
s.contains(['*', '?', '[', ']', '(', ')'])
}

fn escape_for_regex(s: &str) -> String {
let mut escaped = String::new();
for c in s.chars() {
if brush_parser::pattern::regex_char_needs_escaping(c) {
escaped.push('\\');
}
escaped.push(c);
}
escaped
}

fn pattern_to_regex_str(
pattern: &str,
enable_extended_globbing: bool,
) -> Result<String, error::Error> {
// TODO: pattern matching with **
if pattern.contains("**") {
return error::unimp("pattern matching with '**' pattern");
}

Ok(brush_parser::pattern::pattern_to_regex_str(
pattern,
enable_extended_globbing,
Expand Down
12 changes: 12 additions & 0 deletions brush-parser/src/pattern.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,18 @@ mod tests {
use super::*;
use anyhow::Result;

#[test]
fn test_bracket_exprs() -> Result<()> {
assert_eq!(pattern_to_regex_str("[a-z]", true)?, "[a-z]");
assert_eq!(pattern_to_regex_str("[abc]", true)?, "[abc]");
assert_eq!(pattern_to_regex_str(r"[\(]", true)?, r"[\(]");
assert_eq!(pattern_to_regex_str(r"[(]", true)?, "[(]");
assert_eq!(pattern_to_regex_str("[[:digit:]]", true)?, "[[:digit:]]");
assert_eq!(pattern_to_regex_str(r"[-(),!]*", true)?, r"[-(),!].*");
assert_eq!(pattern_to_regex_str(r"[-\(\),\!]*", true)?, r"[-\(\),\!].*");
Ok(())
}

#[test]
fn test_extended_glob() -> Result<()> {
assert_eq!(
Expand Down
7 changes: 7 additions & 0 deletions brush-shell/tests/cases/patterns.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -267,3 +267,10 @@ cases:
myfunc abc
myfunc "*"
- name: "Pattern matching: character sets"
stdin: |
[[ "x" == [a-z] ]] && echo "1. Matched"
[[ "x" == [xyz] ]] && echo "2. Matched"
[[ "1" == [[:digit:]] ]] && echo "3. Matched"
[[ "(" == [\(] ]] && echo "4. Matched"

0 comments on commit a2db75f

Please sign in to comment.