Skip to content

Improve shell quote handling with proper nested quote support#217

Merged
branchseer merged 5 commits intomainfrom
claude/fix-vite-prepare-task-aBQD1
Mar 10, 2026
Merged

Improve shell quote handling with proper nested quote support#217
branchseer merged 5 commits intomainfrom
claude/fix-vite-prepare-task-aBQD1

Conversation

@branchseer
Copy link
Copy Markdown
Member

@branchseer branchseer commented Mar 10, 2026

Summary

Replace unquote_str with brush_parser::word::parse for context-aware shell unquoting. The old function stripped all quote characters uniformly, breaking commands with nested quotes.

Example

A prepare script like:

{
  "prepare": "node -e \"const v = parseInt(process.versions.node, 10); if (v >= 20) require('child_process').execSync('vp config', {stdio: 'inherit'});\""
}

Was parsed incorrectly because unquote_str stripped the single quotes inside the double-quoted string:

- require(child_process).execSync(vp config, {stdio: inherit});
+ require('child_process').execSync('vp config', {stdio: 'inherit'});

Test plan

  • cargo test -p vite_shell — all 7 tests pass
  • test_unquote_preserves_nested_quotes — single quotes in double quotes, double quotes in single quotes, escape sequences
  • test_flatten_pieces_recursion — recursive flattening through word::parse, bail on $VAR and $(cmd)
  • test_parse_urllib_prepare — real-world prepare script with nested quotes

https://claude.ai/code/session_01SoJXo78ET9sowKTSdAuFAg

claude added 3 commits March 10, 2026 13:12
The previous `unquote_str` function naively stripped all quote characters
regardless of context, causing single quotes inside double-quoted strings
to be removed. This corrupted arguments like:
  node -e "require('child_process').execSync('vp config')"
where 'child_process' would lose its quotes, breaking the JavaScript.

Replace with `brush_parser::word::parse` which properly parses word
pieces with quoting context, then flatten the pieces to extract literal
text. This correctly preserves single quotes inside double quotes and
vice versa.

Fixes running `prepare` script from packages like node-modules/urllib.

https://claude.ai/code/session_01SoJXo78ET9sowKTSdAuFAg
Tests DoubleQuotedSequence recursion with escape sequences, literal
single quotes, and bail-out on parameter expansion / command substitution.

https://claude.ai/code/session_01SoJXo78ET9sowKTSdAuFAg
@branchseer branchseer requested a review from fengmk2 March 10, 2026 13:36
claude added 2 commits March 10, 2026 14:34
The test helper `parse_and_flatten` necessarily uses `String` because the
underlying `flatten_pieces` function takes `&mut String`. Added `#[expect]`
attributes matching the pattern already used in production code.

https://claude.ai/code/session_01SoJXo78ET9sowKTSdAuFAg
Replace disallowed String type with vite_str::Str in unquote() and
flatten_pieces(), removing the need for #[expect(clippy::disallowed_types)]
attributes and redundant .into() conversions at call sites.

https://claude.ai/code/session_01SoJXo78ET9sowKTSdAuFAg
@branchseer branchseer merged commit 203440c into main Mar 10, 2026
6 checks passed
@branchseer branchseer deleted the claude/fix-vite-prepare-task-aBQD1 branch March 10, 2026 14:49
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.

3 participants