Skip to content

fix(parser): keep backslash-escaped $ literal in unquoted words - #2563

Merged
chaliy merged 1 commit into
mainfrom
claude/escaped-dollar
Oct 7, 2026
Merged

chaliy merged 1 commit into
mainfrom
claude/escaped-dollar

Conversation

@chaliy

@chaliy chaliy commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

Requested by Михайло · project thread

What changed

A backslash outside quotes now keeps $ and ` literal in unquoted words. The lexer emits the same NUL literal marker it already uses for "\$", so parse_word no longer starts an expansion there.

Why

echo \$HOME expanded the variable. Scripts that generate other scripts (printf '%s\n' \$1, x=\$PATH) got the wrong text.

Before

$ bashkit -c 'HOME=/h; echo \$HOME a\$HOME \${HOME}'
/h a/h /h

After

$ bashkit -c 'HOME=/h; echo \$HOME a\$HOME \${HOME}'
$HOME a$HOME ${HOME}

New spec escaped-dollar.test.sh (4 cases) matches real bash; 3 of them failed before the change.

Risk

Low. One lexer branch; the sentinel is already handled everywhere parse_word consumes words.

Checklist

  • Failing spec first, compared with bash
  • cargo test -p bashkit --lib, integration tests
  • knowledge/log.md

https://claude.ai/code/session_019aFikmptPc91Fj4N2iDXQA


Generated by Claude Code

@chaliy chaliy self-assigned this Oct 7, 2026
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
bashkit 79f40ae Commit Preview URL

Branch Preview URL
Oct 07 2026, 02:13 PM

@chaliy
chaliy force-pushed the claude/escaped-dollar branch from e5b6f8f to 79f40ae Compare October 7, 2026 14:11
@chaliy
chaliy merged commit 2a2ae28 into main Oct 7, 2026
43 checks passed
@chaliy
chaliy deleted the claude/escaped-dollar branch October 7, 2026 14:42
chaliy added a commit that referenced this pull request Oct 7, 2026
<!-- ccr-projects-attribution: {"github_login":"chaliy"} -->
_Requested by **Михайло** · [project
thread](https://claude.ai/code/project/chan_019YEkBJuZMHJdXrjom86cGX?thread=cmsg_019YEkBJuZMHJdXrjom86cGX6hNmzgZPpfCgsgRMptbhdM)_

Stacked on #2563 (retargets to main when that merges).

## What changed

Quoted or backslash-escaped glob characters are literal, as in bash:

- Words: `a\*`, `a"*"` and `a'?'` no longer glob.
- `case` and `[[ == ]]` patterns: `"$x"`, `'a*'`, `a\*` and `\[s\]`
match literally.
- Mixed words: `"*"zz*` with no match prints `*zz*` (the internal
escapes used to leak). `"$x"zz*` reads `$x`, not `$xzz`.
- Single-quoted prefixes: `'a'$x` expands and `'a'*` globs. Both used to
be literal.
- `a{1,2}"*"` still brace-expands.

## Why

These are fidelity bugs from step 1 of the roadmap. A `case` or `[[ ]]`
on a quoted variable that holds `*`, `?` or `[` took the wrong branch.

## Before

```
$ cd /tmp/x && touch ab ac 'a*b' axb
$ echo a\* ; echo "*"zz* ; x='a*'; echo "$x"zz*
ab ac
\*zz*
a*b axb
$ case ab in "$x") echo glob;; *) echo literal;; esac
glob
```

## After

```
a*
*zz*
a*zz*
literal
```

The new spec `escaped-glob.test.sh` (6 cases) matches real bash.

## Risk

Medium, because it touches the lexer's word classification.

- The `QuotedGlobWord` convention (quoted glob characters
backslash-escaped) now covers `read_word` and single-quoted words, with
quote markers.
- `expand_word` unescapes for non-glob uses. Assignments and script
analysis unescape literal parts.
- Known gap: data from an unquoted expansion in such a word loses `\`
before glob characters when nothing matches.
- Documented in `knowledge/foundations/parser.md`.

## Checklist

- [x] Failing spec first, compared with bash
- [x] `cargo test -p bashkit --lib`, integration tests, clippy, fmt
- [x] knowledge updated

https://claude.ai/code/session_019aFikmptPc91Fj4N2iDXQA

---
_Generated by [Claude
Code](https://claude.ai/code/session_019aFikmptPc91Fj4N2iDXQA)_
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.

1 participant