Fixes bug#40694
This allows whitespace and any other text on the line when changing drive letters. Mostly I expect it crops up when commands are concatenated and the readability whitespace is added to the end of the command. For example C: & dir results in "C: " and "dir" as the two commands. We cannot unconditionally remove whitespace as some commands rely on it.
Signed-off-by: Jason Edmeades us@edmeades.me.uk --- programs/cmd/tests/test_builtins.cmd | 35 ++++++++++++++++++++++++ programs/cmd/tests/test_builtins.cmd.exp | 7 +++++ programs/cmd/wcmdmain.c | 9 ++++-- 3 files changed, 49 insertions(+), 2 deletions(-)
diff --git a/programs/cmd/tests/test_builtins.cmd b/programs/cmd/tests/test_builtins.cmd index 6f2ef4a843..49c2d9e1c4 100644 --- a/programs/cmd/tests/test_builtins.cmd +++ b/programs/cmd/tests/test_builtins.cmd @@ -3042,6 +3042,41 @@ echo ------------ Testing start /W ------------ echo start /W failed to wait>foobar.txt start /W "" cmd /C "ping -n1 & echo start /W seems to really wait>foobar.txt"& type foobar.txt& del foobar.txt
+echo ------------ Testing changing the drive letter ---------- +pushd C:\ + +echo Normal: +call :setError 0 +C: +if errorlevel 1 echo Normal drive change failed + +echo Normal+space +call :setError 0 +C:@space@ +if errorlevel 1 echo Normal+space drive change failed + +echo Normal+space+garbage +call :setError 0 +C: garbage +if errorlevel 1 echo Normal+space+garbage drive change failed + +call :setError 0 +echo Quoted should fail +"C:" +if not errorlevel 1 echo quoted drive change unexpectedly worked + +echo Normal+tab +call :setError 0 +C:@tab@ +if errorlevel 1 echo Normal+tab drive change failed + +echo Normal+tab+garbage +call :setError 0 +C:@tab@garbagetab +if errorlevel 1 echo Normal+tab+garbage drive change failed + +popd + echo ------------ Testing combined CALLs/GOTOs ------------ echo @echo off>foo.cmd echo goto :eof>>foot.cmd diff --git a/programs/cmd/tests/test_builtins.cmd.exp b/programs/cmd/tests/test_builtins.cmd.exp index 0eb5b966e8..cfde83b063 100644 --- a/programs/cmd/tests/test_builtins.cmd.exp +++ b/programs/cmd/tests/test_builtins.cmd.exp @@ -1588,6 +1588,13 @@ PATH=try2 PATH=try3 ------------ Testing start /W ------------ start /W seems to really wait +------------ Testing changing the drive letter ---------- +Normal: +Normal+space +Normal+space+garbage +Quoted should fail +Normal+tab +Normal+tab+garbage ------------ Testing combined CALLs/GOTOs ------------ world cheball diff --git a/programs/cmd/wcmdmain.c b/programs/cmd/wcmdmain.c index 827ddd2121..0d02f1f388 100644 --- a/programs/cmd/wcmdmain.c +++ b/programs/cmd/wcmdmain.c @@ -1327,13 +1327,18 @@ void WCMD_execute (const WCHAR *command, const WCHAR *redirects, cmd = new_cmd;
/* - * Changing default drive has to be handled as a special case. + * Changing default drive has to be handled as a special case, anything + * else if it exists after whitespace is ignored */
- if ((strlenW(cmd) == 2) && (cmd[1] == ':') && IsCharAlphaW(cmd[0])) { + if ((cmd[1] == ':') && IsCharAlphaW(cmd[0]) && + (!cmd[2] || cmd[2] == ' ' || cmd[2] == '\t')) { WCHAR envvar[5]; WCHAR dir[MAX_PATH];
+ /* Ignore potential garbage on the same line */ + cmd[2]=0x00; + /* According to MSDN CreateProcess docs, special env vars record the current directory on each drive, in the form =C: so see if one specified, and if so go back to it */