Skip to content

Commit 9e7dd28

Browse files
committed
syntax: don't treat '#' as a comment inside [[ ]] tests
The lexer treated '#' as the start of a comment whenever the parser quote state was not unquotedWordCont, which meant that mid-word '#' inside [[ ]] tests was wrongly consumed as a comment. This broke expressions like [[ -n $foo#bar ]] and zsh glob qualifiers like [[ -n ./(../)#(.jj)(#qN/) ]], where parsing fell off the end of the test clause. Allow '#' as a word continuation in testExpr too when adjacent to the previous token, since '#' has no comment meaning inside [[ ]]. Fixes #1326.
1 parent fcd06d4 commit 9e7dd28

2 files changed

Lines changed: 10 additions & 1 deletion

File tree

syntax/filetests_test.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4021,6 +4021,14 @@ var fileTests = []fileTestCase{
40214021
X: litWord("a"),
40224022
}}, LangBash),
40234023
),
4024+
fileTest(
4025+
// '#' inside [[ ]] is part of a word, not a comment.
4026+
[]string{"[[ -n $foo#bar ]]"},
4027+
langFile(&TestClause{X: &UnaryTest{
4028+
Op: TsNempStr,
4029+
X: word(litParamExp("foo"), lit("#bar")),
4030+
}}, LangBash|LangMirBSDKorn|LangZsh),
4031+
),
40244032
fileTest(
40254033
[]string{"[[ a =~ b ]]", "[[ a =~ b ]];"},
40264034
langFile(&TestClause{X: &BinaryTest{

syntax/lexer.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,8 @@ skipSpace:
294294
case '#':
295295
// If we're parsing $foo#bar, ${foo}#bar, 'foo'#bar, or "foo"#bar,
296296
// #bar is a continuation of the same word, not a comment.
297-
if p.quote == unquotedWordCont && !p.spaced {
297+
// The same applies inside [[ ]] tests, where '#' has no comment meaning.
298+
if !p.spaced && (p.quote == unquotedWordCont || p.quote == testExpr) {
298299
p.advanceLitNone(r)
299300
return
300301
}

0 commit comments

Comments
 (0)