[PATCH 2/3] [cmd] Fix 'for' expansion of wildcards when no args are supplied

Jason Edmeades jason at edmeades.me.uk
Tue Jun 4 16:07:11 CDT 2013


If the thing being iterated on contains a wildcard, the root path
supplied is used in the output if it has windows slashes in. As an
aside while testing this I noticed that supplying unix slashes
works but strips off the path, hence the fix looks specifically for
windows backslashes only.

[Fixes bug 33253]
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.winehq.org/pipermail/wine-patches/attachments/20130604/ab1e1a38/attachment-0001.html>
-------------- next part --------------
From e318a0ad34628607fcb7a564b87440e88afcc89f Mon Sep 17 00:00:00 2001
From: Jason Edmeades <jason at edmeades.me.uk>
Date: Tue, 4 Jun 2013 00:29:51 +0100
Subject: [PATCH 2/3] [cmd] Fix 'for' expansion of wildcards when no args are
 supplied

If the thing being iterated on contains a wildcard, the root path
supplied is used in the output if it has windows slashes in. As an
aside while testing this I noticed that supplying unix slashes
works but strips off the path, hence the fix looks specifically for
windows backslashes only.

[Fixes bug 33253]
---
 programs/cmd/builtins.c                  |    8 ++++++--
 programs/cmd/tests/test_builtins.cmd     |   17 ++++++++++++++++-
 programs/cmd/tests/test_builtins.cmd.exp |   12 ++++++++++++
 3 files changed, 34 insertions(+), 3 deletions(-)

diff --git a/programs/cmd/builtins.c b/programs/cmd/builtins.c
index c2ccdc8..aa1e7d4 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 48a8362..78f7cdc 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 77e4178..7380185 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
-- 
1.7.9.5


More information about the wine-patches mailing list