diff --git a/crates/bashkit/src/interpreter/glob.rs b/crates/bashkit/src/interpreter/glob.rs index f849a0ff..5ed7b280 100644 --- a/crates/bashkit/src/interpreter/glob.rs +++ b/crates/bashkit/src/interpreter/glob.rs @@ -244,6 +244,9 @@ impl Interpreter { } } (Some('['), Some(v)) => { + // Save state before consuming '[' — if bracket expr is + // invalid (e.g. "[]"), we fall back to literal '[' match. + let saved_pattern = pattern_chars.clone(); pattern_chars.next(); // consume '[' let match_char = if nocase { v.to_ascii_lowercase() } else { v }; if let Some(matched) = @@ -255,8 +258,20 @@ impl Interpreter { return false; } } else { - // Invalid bracket expression, treat '[' as literal - return false; + // Invalid bracket expression — treat '[' as literal + pattern_chars = saved_pattern; + pattern_chars.next(); // consume '[' as literal + let p = '['; + let match_ok = if nocase { + p.eq_ignore_ascii_case(&v) + } else { + p == v + }; + if match_ok { + value_chars.next(); + } else { + return false; + } } } (Some('['), None) => return false, diff --git a/crates/bashkit/tests/spec_cases/bash/conditional.test.sh b/crates/bashkit/tests/spec_cases/bash/conditional.test.sh index 017b7aca..4aaea282 100644 --- a/crates/bashkit/tests/spec_cases/bash/conditional.test.sh +++ b/crates/bashkit/tests/spec_cases/bash/conditional.test.sh @@ -181,3 +181,26 @@ correct ### expect yes ### end + +### cond_bracket_literal_match +# Issue #837: [] should be treated as literal when it's an invalid glob +x="[]" +if [[ "$x" == "[]" ]]; then echo match; else echo "no match"; fi +### expect +match +### end + +### cond_single_bracket_literal +# Literal [ comparison +x="[" +[[ "$x" == "[" ]] && echo match || echo "no match" +### expect +match +### end + +### cond_valid_glob_bracket +# Valid glob [a] should still work as pattern +[[ "a" == [a] ]] && echo match || echo "no match" +### expect +match +### end