Skip to content

Quote arguments holding cmd.exe special characters - #36

Merged
HalRiveria merged 2 commits into
mainfrom
fix/cmd-metacharacters
Nov 6, 2026
Merged

HalRiveria merged 2 commits into
mainfrom
fix/cmd-metacharacters

Conversation

@HalRiveria-Bot

Copy link
Copy Markdown
Collaborator

What was wrong

A .bat or .cmd program runs through cmd.exe, which acts on &, |, <, > and ^ outside quotes and splits batch arguments at , and ;. A list element only got quoted when it held a space, tab or quote, so a list in Arguments passed elements like these to cmd as they were:

Element What a batch file got
a&ver a, and ver ran
a|b nothing; cmd tried to run b
a^b ab
a,b / a;b two arguments

File names can contain &, ^, , and ;, so a batch over real files could run commands built from their names.

What changed

  • ConvertTo-PkArgumentString, which list Arguments go through, also quotes an element holding & | < > ^ ( ) , ;. Programs that use the C runtime's rules drop the quotes, so they get the same arguments as before.
  • The help and README say what quoting can't cover for these programs:
    • %NAME% is expanded even inside quotes.
    • = still splits batch arguments. It's left unquoted because some programs, such as msiexec, read NAME=value from the command line themselves.
    • An element containing a " can end up partly unquoted, because cmd counts an escaped \" as a quote.

Things that change for users:

  • A list passed to cmd.exe /c now has these arguments quoted.
  • A program that reads its raw command line sees the new quotes.
  • A trailing backslash in a newly quoted argument is doubled, as it already was for arguments with spaces, so a batch file sees \\.

Testing

  • New harness checks:

    • the exact quoted output for each character
    • an ordinary program still gets each element exactly
    • a real .cmd file gets each of a&ver, a|b, a^b, a,b, a;b and (x) as one argument, with nothing else run

    Five of the .cmd checks and the quoting check fail on main.

  • Full harness: ALL PASSED (387 assertions) on Windows PowerShell 5.1 and PowerShell 7, none skipped.

🤖 Generated with Claude Code

HalRiveria and others added 2 commits November 6, 2026 09:30
A .bat or .cmd program runs through cmd.exe, which acts on & | < > ^ outside
quotes and splits batch arguments at , ; so an Arguments list element like
'a&ver', with no space to trigger quoting, ran ver instead of reaching the
program. ConvertTo-PkArgumentString, and with it list Arguments, now quotes
any element holding one of & | < > ^ ( ) , ; - harmless to programs that use
the C runtime's rules, which drop the quotes. The README notes that cmd.exe
still expands %NAME% inside quotes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
cmd.exe also splits batch arguments at =, which stays unquoted because some
programs read NAME=value from the command line themselves, and it counts an
escaped \" as a quote, so an argument containing a quote can end up partly
unquoted. The help and README now say so, next to %NAME% expansion.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@HalRiveria
HalRiveria merged commit 0c651fc into main Nov 6, 2026
2 checks passed
@HalRiveria
HalRiveria deleted the fix/cmd-metacharacters branch November 6, 2026 14:39
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.

2 participants