Skip to content

Commit 2fbcd5e

Browse files
committed
fix(parser): preserve literal quoting in =~ regex patterns
1 parent d76881f commit 2fbcd5e

2 files changed

Lines changed: 13 additions & 3 deletions

File tree

‎crates/bashkit/src/interpreter/mod.rs‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12121,6 +12121,16 @@ echo "count=$COUNT"
1212112121
assert_eq!(result.stdout.trim(), "match");
1212212122
}
1212312123

12124+
#[tokio::test]
12125+
async fn test_regex_single_quoted_pattern_is_literal() {
12126+
let mut bash = crate::Bash::new();
12127+
let result = bash
12128+
.exec(r#"re="200"; line="hello 200 world"; [[ $line =~ '$re' ]] && echo "match" || echo "no""#)
12129+
.await
12130+
.unwrap();
12131+
assert_eq!(result.stdout.trim(), "no");
12132+
}
12133+
1212412134
#[tokio::test]
1212512135
async fn test_assoc_array_in_double_quotes() {
1212612136
let mut bash = crate::Bash::new();

‎crates/bashkit/src/parser/mod.rs‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1464,10 +1464,10 @@ impl<'a> Parser<'a> {
14641464

14651465
// After =~, handle regex pattern.
14661466
// If the pattern contains $ (variable reference), parse it as a
1467-
// normal word so variables expand. Otherwise collect as literal
1468-
// regex to preserve parens, backslashes, etc.
1467+
// normal word so variables expand. Keep quoted/literal tokens as
1468+
// literal regex patterns to preserve shell quoting semantics.
14691469
if saw_regex_op {
1470-
if w_clone.contains('$') && !is_quoted {
1470+
if w_clone.contains('$') && !is_quoted && !is_literal {
14711471
// Variable reference — parse normally for expansion
14721472
let parsed = self.parse_word(w_clone);
14731473
words.push(parsed);

0 commit comments

Comments
 (0)