Jason Edmeades : cmd: Handle whitespace in 'for' argument items.

Alexandre Julliard julliard at winehq.org
Tue Sep 11 14:53:20 CDT 2018


Module: wine
Branch: master
Commit: becfbb80b4e80680b32cc240b2465e4972590b14
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=becfbb80b4e80680b32cc240b2465e4972590b14

Author: Jason Edmeades <us at edmeades.me.uk>
Date:   Mon Sep 10 23:30:18 2018 +0100

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=45731
Signed-off-by: Jason Edmeades <us at edmeades.me.uk>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 programs/cmd/builtins.c                  | 8 +++++++-
 programs/cmd/tests/test_builtins.cmd     | 7 ++++++-
 programs/cmd/tests/test_builtins.cmd.exp | 4 ++++
 3 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/programs/cmd/builtins.c b/programs/cmd/builtins.c
index 25d5be1..1e6181d 100644
--- a/programs/cmd/builtins.c
+++ b/programs/cmd/builtins.c
@@ -2069,17 +2069,22 @@ static HANDLE WCMD_forf_getinputhandle(BOOL usebackq, WCHAR *itemstr, BOOL iscmd
   WCHAR  temp_str[MAX_PATH];
   WCHAR  temp_file[MAX_PATH];
   WCHAR  temp_cmd[MAXSTRING];
+  WCHAR *trimmed = NULL;
   HANDLE hinput = INVALID_HANDLE_VALUE;
   static const WCHAR redirOutW[]  = {'>','%','s','\0'};
   static const WCHAR cmdW[]       = {'C','M','D','\0'};
   static const WCHAR cmdslashcW[] = {'C','M','D','.','E','X','E',' ',
                                      '/','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)) ||
       (iscmd && (itemstr[0] == '\'' && !usebackq)) ||
       (!iscmd && (itemstr[0] == '"' && usebackq)))
   {
+    trimmed = WCMD_strtrim(itemstr);
+    if (trimmed) {
+      itemstr = trimmed;
+    }
     itemstr[strlenW(itemstr)-1] = 0x00;
     itemstr++;
   }
@@ -2106,6 +2111,7 @@ static HANDLE WCMD_forf_getinputhandle(BOOL usebackq, WCHAR *itemstr, BOOL iscmd
     hinput = CreateFileW(itemstr, GENERIC_READ, FILE_SHARE_READ,
                         NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
   }
+  heap_free(trimmed);
   return hinput;
 }
 
diff --git a/programs/cmd/tests/test_builtins.cmd b/programs/cmd/tests/test_builtins.cmd
index de9c889..e74d491 100644
--- a/programs/cmd/tests/test_builtins.cmd
+++ b/programs/cmd/tests/test_builtins.cmd
@@ -1702,8 +1702,11 @@ mkdir foobar & cd foobar
 echo ------ string argument
 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 X%%iX
 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)
+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 usebackq %%i in ('a ') do echo %%i>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
 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 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
 :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
 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
diff --git a/programs/cmd/tests/test_builtins.cmd.exp b/programs/cmd/tests/test_builtins.cmd.exp
index 3829318..021a5b0 100644
--- a/programs/cmd/tests/test_builtins.cmd.exp
+++ b/programs/cmd/tests/test_builtins.cmd.exp
@@ -1180,7 +1180,9 @@ WINE_bar correctly 6 at or_broken@ERROR: WINE_bar incorrectly 5 [6]
 --- for /F
 ------ string argument
 a
+XaX
 a at or_broken@no output
+XaX at or_broken@no output
 a
 a at or_broken@no output
 a
@@ -1218,6 +1220,8 @@ Passed2 at or_broken@Missing functionality - Broken2
 Passed3 at or_broken@Missing functionality - Broken3
 Passed4 at or_broken@Missing functionality - Broken4
 Passed5 at or_broken@Missing functionality - Broken5
+Passed6 at or_broken@Missing functionality - Broken6
+Passed7 at or_broken@Missing functionality - Broken7
 ------ eol option
 and at or_broken@Broken NT4 functionality1
 Line at or_broken@Broken NT4 functionality2




More information about the wine-cvs mailing list