Skip to content

fix(shell_cmd): accept Windows paths in quoted arguments, and refuse what cmd.exe expands - #183

Merged
srpatcha merged 3 commits into
masterfrom
fix/shell-arg-windows-paths
Oct 2, 2026
Merged

srpatcha merged 3 commits into
masterfrom
fix/shell-arg-windows-paths

Conversation

@srpatcha

@srpatcha srpatcha commented Oct 2, 2026

Copy link
Copy Markdown
Member

Fixes #182

Master's Windows MSVC leg has been red since #156, because eos_shell_arg_is_safe() refuses \ and so every Windows path. It also blocks #179 and #181.

POSIX (unchanged) Windows (new)
\ refused accepted (path separator, inert inside quotes)
trailing \ refused refused (the CRT reads \" as a literal quote)
% ! allowed refused (cmd.exe expands them inside quotes)
`;|&><$()"'``, control characters refused refused

WSL host: ctest 46/46, test_shell_cmd 12/12. Windows: compiles with -D_WIN32 -fsyntax-only. The MSVC CI leg on this PR is the real check.

…what cmd.exe expands

eos_shell_arg_is_safe() refused the backslash everywhere. That is correct
for a POSIX shell, which reads \ inside double quotes. On Windows it is the
path separator, so after #156 the cargo/pip/npm backends refused every
real path, and the MSVC leg failed test_backend_install with 0xc0000409.

On Windows the rule now follows cmd.exe and the CRT:
- a backslash is accepted, since it means nothing inside double quotes;
- a trailing backslash is refused, because the CRT reads \" as a literal
  quote and the arguments after it would merge;
- %VAR% and !VAR! are refused, because they expand even inside quotes.
The POSIX rule is unchanged, and tests assert both. Host ctest passes
46/46 and test_shell_cmd 12/12. The Windows branch compiles with
-D_WIN32 -fsyntax-only, but has not been run on Windows here; the MSVC CI
leg is the check.

Fixes #182
The Windows install ran 'copy *.bin & copy *.elf & copy *.hex' through
cmd.exe and took its exit status from the last copy. A build that produced
app.bin but no .hex was reported as a failed install, which is what
test_backend_install hit on the MSVC leg once Windows paths were accepted
(test_backend_install.c:231).

It now does what the POSIX find does, in-process with Win32: refuse a
missing build directory, create install_dir, and copy each *.bin, *.elf and
*.hex that exists. A kind with no match is not an error. A failed copy or
an over-long path is. The POSIX branch is unchanged.

Checked here: host ctest 46/46, and a -D_WIN32 -Wall -Wextra syntax check
against a minimal windows.h stub. Not run on Windows; the MSVC CI leg is
the check.

Refs #182
…as every backend does

test_shell_cmd's test_every_backend_refuses_a_hostile_directory requires
EOS_ERR_INVALID for a directory like '/tmp/build"; touch pwned; "'. The
in-process Windows install never runs a shell, so the name is harmless
there, but it returned EOS_ERR_NOT_FOUND. It now applies the same
eos_shell_arg_is_safe() check first, so every backend keeps one contract.

Refs #182
@srpatcha
srpatcha merged commit 6a37953 into master Oct 2, 2026
31 checks passed
@srpatcha
srpatcha deleted the fix/shell-arg-windows-paths branch October 2, 2026 04:08
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.

Windows: the checked shell builder refuses every path (backslash), so backend installs fail on MSVC

1 participant