Commit becfbb80 authored by Jason Edmeades's avatar Jason Edmeades Committed by Alexandre Julliard

cmd: Handle whitespace in 'for' argument items.

Avoid whitespace affecting the parsing of a for loops items. The leading and trailing quote or backtick needed removing, and it was assumed that the trailing character would be that character, which was wrong when there was whitespace unless the parameter is trimmed. Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=45731Signed-off-by: 's avatarJason Edmeades <us@edmeades.me.uk> Signed-off-by: 's avatarAlexandre Julliard <julliard@winehq.org>
parent b6774e38
...@@ -2069,17 +2069,22 @@ static HANDLE WCMD_forf_getinputhandle(BOOL usebackq, WCHAR *itemstr, BOOL iscmd ...@@ -2069,17 +2069,22 @@ static HANDLE WCMD_forf_getinputhandle(BOOL usebackq, WCHAR *itemstr, BOOL iscmd
WCHAR temp_str[MAX_PATH]; WCHAR temp_str[MAX_PATH];
WCHAR temp_file[MAX_PATH]; WCHAR temp_file[MAX_PATH];
WCHAR temp_cmd[MAXSTRING]; WCHAR temp_cmd[MAXSTRING];
WCHAR *trimmed = NULL;
HANDLE hinput = INVALID_HANDLE_VALUE; HANDLE hinput = INVALID_HANDLE_VALUE;
static const WCHAR redirOutW[] = {'>','%','s','\0'}; static const WCHAR redirOutW[] = {'>','%','s','\0'};
static const WCHAR cmdW[] = {'C','M','D','\0'}; static const WCHAR cmdW[] = {'C','M','D','\0'};
static const WCHAR cmdslashcW[] = {'C','M','D','.','E','X','E',' ', static const WCHAR cmdslashcW[] = {'C','M','D','.','E','X','E',' ',
'/','C',' ','%','s','\0'}; '/','C',' ','%','s','\0'};
/* Remove leading and trailing character */ /* Remove leading and trailing character (but there may be trailing whitespace too) */
if ((iscmd && (itemstr[0] == '`' && usebackq)) || if ((iscmd && (itemstr[0] == '`' && usebackq)) ||
(iscmd && (itemstr[0] == '\'' && !usebackq)) || (iscmd && (itemstr[0] == '\'' && !usebackq)) ||
(!iscmd && (itemstr[0] == '"' && usebackq))) (!iscmd && (itemstr[0] == '"' && usebackq)))
{ {
trimmed = WCMD_strtrim(itemstr);
if (trimmed) {
itemstr = trimmed;
}
itemstr[strlenW(itemstr)-1] = 0x00; itemstr[strlenW(itemstr)-1] = 0x00;
itemstr++; itemstr++;
} }
...@@ -2106,6 +2111,7 @@ static HANDLE WCMD_forf_getinputhandle(BOOL usebackq, WCHAR *itemstr, BOOL iscmd ...@@ -2106,6 +2111,7 @@ static HANDLE WCMD_forf_getinputhandle(BOOL usebackq, WCHAR *itemstr, BOOL iscmd
hinput = CreateFileW(itemstr, GENERIC_READ, FILE_SHARE_READ, hinput = CreateFileW(itemstr, GENERIC_READ, FILE_SHARE_READ,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
} }
heap_free(trimmed);
return hinput; return hinput;
} }
......
...@@ -1702,8 +1702,11 @@ mkdir foobar & cd foobar ...@@ -1702,8 +1702,11 @@ mkdir foobar & cd foobar
echo ------ string argument echo ------ string argument
rem NT4 does not support usebackq rem NT4 does not support usebackq
for /F %%i in ("a b c") do echo %%i for /F %%i in ("a b c") do echo %%i
for /F %%i in ( "a b c" ) do echo X%%iX
for /f usebackq %%i in ('a b c') do echo %%i>output_file for /f usebackq %%i in ('a b c') do echo %%i>output_file
if not exist output_file (echo no output) else (type output_file & del output_file) if not exist output_file (echo no output) else (type output_file & del output_file)
for /f usebackq %%i in ( 'a b c' ) do echo X%%iX>output_file
if not exist output_file (echo no output) else (type output_file & del output_file)
for /f %%i in ("a ") do echo %%i for /f %%i in ("a ") do echo %%i
for /f usebackq %%i in ('a ') do echo %%i>output_file for /f usebackq %%i in ('a ') do echo %%i>output_file
if not exist output_file (echo no output) else (type output_file & del output_file) if not exist output_file (echo no output) else (type output_file & del output_file)
...@@ -1755,9 +1758,11 @@ for /f "usebackq" %%i in (`echo.Passed2`) do echo %%i ...@@ -1755,9 +1758,11 @@ for /f "usebackq" %%i in (`echo.Passed2`) do echo %%i
for /f usebackq %%i in (`echo.Passed3`) do echo %%i for /f usebackq %%i in (`echo.Passed3`) do echo %%i
for /f "usebackq" %%i in (`"c:\windows\system32\cmd.exe" /C echo Passed4`) do echo %%i for /f "usebackq" %%i in (`"c:\windows\system32\cmd.exe" /C echo Passed4`) do echo %%i
for /f "usebackq" %%i in (`""c:\windows\system32\cmd.exe" /C echo Passed5"`) do echo %%i for /f "usebackq" %%i in (`""c:\windows\system32\cmd.exe" /C echo Passed5"`) do echo %%i
for /f %%i in ( 'echo.Passed6' ) do echo %%i
for /f "usebackq" %%i in ( `echo.Passed7` ) do echo %%i
goto :ContinueFORF goto :ContinueFORF
:SkipFORFcmdNT4 :SkipFORFcmdNT4
for /l %%i in (1,1,5) do echo Missing functionality - Broken%%i for /l %%i in (1,1,7) do echo Missing functionality - Broken%%i
:ContinueFORF :ContinueFORF
rem FIXME: Rest not testable right now in wine: not implemented and would need rem FIXME: Rest not testable right now in wine: not implemented and would need
rem preliminary grep-like program implementation (e.g. like findstr or fc) even rem preliminary grep-like program implementation (e.g. like findstr or fc) even
......
...@@ -1180,7 +1180,9 @@ WINE_bar correctly 6@or_broken@ERROR: WINE_bar incorrectly 5 [6] ...@@ -1180,7 +1180,9 @@ WINE_bar correctly 6@or_broken@ERROR: WINE_bar incorrectly 5 [6]
--- for /F --- for /F
------ string argument ------ string argument
a a
XaX
a@or_broken@no output a@or_broken@no output
XaX@or_broken@no output
a a
a@or_broken@no output a@or_broken@no output
a a
...@@ -1218,6 +1220,8 @@ Passed2@or_broken@Missing functionality - Broken2 ...@@ -1218,6 +1220,8 @@ Passed2@or_broken@Missing functionality - Broken2
Passed3@or_broken@Missing functionality - Broken3 Passed3@or_broken@Missing functionality - Broken3
Passed4@or_broken@Missing functionality - Broken4 Passed4@or_broken@Missing functionality - Broken4
Passed5@or_broken@Missing functionality - Broken5 Passed5@or_broken@Missing functionality - Broken5
Passed6@or_broken@Missing functionality - Broken6
Passed7@or_broken@Missing functionality - Broken7
------ eol option ------ eol option
and@or_broken@Broken NT4 functionality1 and@or_broken@Broken NT4 functionality1
Line@or_broken@Broken NT4 functionality2 Line@or_broken@Broken NT4 functionality2
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment