fix(windows): preserve quotes in cmd commands (start_process)#495
Conversation
On Windows, start_process spawns the shell executable directly
(`cmd /c <command>`) with useShellOption=false. Node/libuv then applies
its default MSVCRT-style argument quoting, which escapes embedded double
quotes as \". cmd.exe does not treat \" as an escape, so every quoted
command was corrupted before cmd parsed it -- e.g. a quoted path with
spaces ("C:\Program Files\app.exe") or `tasklist /fi "imagename eq x"`
would fail with "syntax incorrect" / "Invalid argument".
Set windowsVerbatimArguments=true for the cmd branch so cmd parses its
own quoting (the same thing Node does internally for `shell: true`).
Scoped to cmd only via a new ShellSpawnConfig.windowsVerbatim flag:
PowerShell/pwsh have different quote rules and must NOT use verbatim
(it splits quoted arguments into separate tokens), and POSIX shells
(bash/zsh/fish, incl. WSL) are unaffected -- windowsVerbatimArguments
is a no-op outside win32. No behaviour change on macOS/Linux.
Before: echo "hello world" a"b"c -> \"hello world\" a\"b\"c
After: echo "hello world" a"b"c -> "hello world" a"b"c
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughThis PR adds Windows-specific argument handling for ChangesWindows cmd.exe Verbatim Argument Handling
Estimated code review effort🎯 2 (Simple) | ⏱️ ~8 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Problem
On Windows,
start_processcorrupts any command containing double quotes when the shell is cmd. Examples that fail today:dir "C:\Program Files\Mozilla Firefox\firefox.exe"-> The filename, directory name, or volume label syntax is incorrect.tasklist /fi "imagename eq firefox.exe"-> ERROR: Invalid argument/option - 'eq'.start "" "C:\Program Files\Mozilla Firefox\firefox.exe"-> silently fails to launchMinimal repro:
Root cause
In
terminal-manager.ts, the cmd branch ofgetShellSpawnArgsreturns{ executable: 'cmd', args: ['/c', command], useShellOption: false }, andexecuteCommandcallsspawn(executable, args, opts)withoutshell: true. Node/libuv then builds the Windows command line using MSVCRT-style quoting, escaping embedded"as\".cmd.exedoes not treat\"as an escape, so the quotes reach cmd mangled and the command breaks. (Node only disables this escaping automatically whenshell: trueis used, which DC deliberately avoids so it can control login flags.)Fix
Set
windowsVerbatimArguments = truefor the cmd branch, so cmd parses its own quoting -- exactly what Node does internally forshell: true.Scoped to cmd only via a new
ShellSpawnConfig.windowsVerbatimflag:"hello world"into separate tokens. They keep their existing behaviour.windowsVerbatimArgumentsis a no-op outside win32, and these already pass the command as a clean-cargument.process.platform === 'win32').Testing
Verified on a live local build (Windows 11, Node 24, cmd default shell):
echo "hello world" a"b"c\"hello world\" a\"b\"c"hello world" a"b"cdir "C:\Program Files\Mozilla Firefox\firefox.exe"tasklist /fi "imagename eq explorer.exe"Invalid argument 'eq'start "" "C:\Program Files\Mozilla Firefox\firefox.exe"PowerShell re-checked after scoping:
echo "hello world"returnshello worldon a single line (correct), confirming no regression.Summary by CodeRabbit
Bug Fixes