diff --git a/programs/cmd/builtins.c b/programs/cmd/builtins.c index c2ccdc86400..aa1e7d4d099 100644 --- a/programs/cmd/builtins.c +++ b/programs/cmd/builtins.c @@ -2237,6 +2237,7 @@ void WCMD_for (WCHAR *p, CMD_LIST **cmdList) { if (!useNumbers && !doFileset) { WCHAR fullitem[MAX_PATH]; + int prefixlen = 0; /* Now build the item to use / search for in the specified directory, as it is fully qualified in the /R case */ @@ -2245,11 +2246,12 @@ void WCMD_for (WCHAR *p, CMD_LIST **cmdList) { strcatW(fullitem, slashW); strcatW(fullitem, item); } else { + WCHAR *prefix = strrchrW(item, '\\'); + if (prefix) prefixlen = (prefix - item) + 1; strcpyW(fullitem, item); } if (strpbrkW (fullitem, wildcards)) { - hff = FindFirstFileW(fullitem, &fd); if (hff != INVALID_HANDLE_VALUE) { do { @@ -2270,7 +2272,9 @@ void WCMD_for (WCHAR *p, CMD_LIST **cmdList) { strcatW(fullitem, slashW); strcatW(fullitem, fd.cFileName); } else { - strcpyW(fullitem, fd.cFileName); + if (prefixlen) lstrcpynW(fullitem, item, prefixlen + 1); + fullitem[prefixlen] = 0x00; + strcatW(fullitem, fd.cFileName); } doExecuted = TRUE; diff --git a/programs/cmd/tests/test_builtins.cmd b/programs/cmd/tests/test_builtins.cmd index 48a836268f8..78f7cdcb9d6 100644 --- a/programs/cmd/tests/test_builtins.cmd +++ b/programs/cmd/tests/test_builtins.cmd @@ -1017,7 +1017,22 @@ for /R %%i in (baz* fred* jim) do call temp.bat %%i call :ValidateExpected echo for /R passed -cd .. & rd /s/Q foobar +echo --- Complex wildcards unix and windows slash +cd .. +echo Windows slashs, valid path +for %%f in (foobar\baz\bazbaz) do echo ASIS: %%f +for %%f in (foobar\baz\*) do echo WC : %%f +echo Windows slashs, invalid path +for %%f in (foobar\jim\bazbaz) do echo ASIS: %%f +for %%f in (foobar\jim\*) do echo WC : %%f +echo Unix slashs, valid path +for %%f in (foobar/baz/bazbaz) do echo ASIS: %%f +for %%f in (foobar/baz/*) do echo WC : %%f +echo Unix slashs, invalid path +for %%f in (foobar/jim/bazbaz) do echo ASIS: %%f +for %%f in (foobar/jim/*) do echo WC : %%f +echo Done +rd /s/Q foobar echo --- for /L rem Some cases loop forever writing 0s, like e.g. (1,0,1), (1,a,3) or (a,b,c); those can't be tested here for /L %%i in (1,2,0) do echo %%i diff --git a/programs/cmd/tests/test_builtins.cmd.exp b/programs/cmd/tests/test_builtins.cmd.exp index 77e417816bf..7380185a819 100644 --- a/programs/cmd/tests/test_builtins.cmd.exp +++ b/programs/cmd/tests/test_builtins.cmd.exp @@ -691,6 +691,18 @@ Mixed enumeration from provided root With duplicates enumeration Strip missing wildcards, keep unwildcarded names for /R passed +--- Complex wildcards unix and windows slash +Windows slashs, valid path +ASIS: foobar\baz\bazbaz +WC : foobar\baz\bazbaz +Windows slashs, invalid path +ASIS: foobar\jim\bazbaz +Unix slashs, valid path +ASIS: foobar/baz/bazbaz +WC : bazbaz +Unix slashs, invalid path +ASIS: foobar/jim/bazbaz +Done --- for /L 1 3