Skip to content

syntax: allow bracket globs in array elements#1324

Open
lawrence3699 wants to merge 1 commit intomvdan:masterfrom
lawrence3699:fix/array-bracket-globs
Open

syntax: allow bracket globs in array elements#1324
lawrence3699 wants to merge 1 commit intomvdan:masterfrom
lawrence3699:fix/array-bracket-globs

Conversation

@lawrence3699
Copy link
Copy Markdown

Fixes #1322.

Array elements in Bash and Zsh can start with bracket globs, but the array-element lexer currently tokenizes every [ as the start of an indexed assignment.

That makes inputs like:

matches=( "${BASE_DIR}/v${YEAR}-"[0-9][0-9]-[0-9][0-9]-[0-9][0-9][0-9][0-9] )

fail with [x] must be followed by '=' even though the shell accepts them.

This change only keeps [ as indexed-assignment syntax in array literals when the matching ] is immediately followed by =. Otherwise, it stays part of the array element word.

I added regression coverage for both a bare bracket glob array element and the quoted-prefix form from the issue.

Tests:

  • go test ./syntax -run 'TestParseFiles/(bash|zsh)'
  • go test ./syntax -run 'TestParseErr/(bash|zsh)'
  • go test ./syntax -run 'TestParseConfirm/(bash|zsh)'
  • go test ./...

Copilot AI review requested due to automatic review settings April 19, 2026 08:58
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the Bash/Zsh lexer/parser to correctly treat [ in array literals as the start of an indexed assignment only when the matching ] is immediately followed by =, allowing bracket-glob array elements like "[0-9]" to parse successfully (fixes #1322).

Changes:

  • Refines array-literal tokenization of [ to disambiguate bracket globs vs indexed assignments.
  • Removes the now-obsolete error expectation for a=([i]) and adds regression parsing coverage.
  • Adds file-based parse tests for both bare bracket-glob array elements and quoted-prefix + bracket-glob words.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
syntax/lexer.go Adds lookahead (arrayIndexAssign) and gates [ tokenization in array elements on ]=.
syntax/parser_test.go Removes an error-case that is now valid under the updated lexer behavior.
syntax/filetests_test.go Adds regression tests ensuring bracket-glob array elements parse in Bash/Zsh.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread syntax/lexer.go
Comment on lines +1072 to +1074
func (p *Parser) arrayIndexAssign() bool {
rest := p.bs[p.bsp:]
depth := 1
Copy link

Copilot AI Apr 19, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

arrayIndexAssign only scans the currently buffered bytes (p.bs[p.bsp:]) and never calls fill/peek to ensure the matching ']' is present. If the ']' (and following '=') lands across a 1KiB buffer boundary (bufSize) or when parsing from slow/interactive readers, rest can be empty/partial and this will fall through to the conservative return true, causing '[' to be tokenized as an indexed assignment and potentially reintroducing the same parse error on otherwise-valid bracket globs. Consider extending the lookahead to read more when needed (similar to zshNumRange), e.g. loop calling fill while searching until you either find the matching ']' (and can check the next byte) or hit EOF / a reasonable limit.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

zsh: extended_glob [x] must be followed by =

2 participants