From 15215bd07193cc31b8372424f181a31aa9364777 Mon Sep 17 00:00:00 2001 From: Jason Edmeades Date: Sun, 24 Jun 2018 21:44:11 +0100 Subject: [PATCH] cmd: Fix subdirectory prefix in for loops. A for loop can be working through a wildcarded subdirectory, but when processing the first file in the subdirectory, it stores the prefix in a static variable which gets overwritten during the 'for' body processing. Signed-off-by: Jason Edmeades Signed-off-by: Alexandre Julliard --- programs/cmd/builtins.c | 10 ++++++++-- programs/cmd/tests/test_builtins.cmd | 7 +++++++ programs/cmd/tests/test_builtins.cmd.exp | 4 ++++ 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/programs/cmd/builtins.c b/programs/cmd/builtins.c index 9fc7502163f..35b68bd45a9 100644 --- a/programs/cmd/builtins.c +++ b/programs/cmd/builtins.c @@ -2261,19 +2261,25 @@ void WCMD_for (WCHAR *p, CMD_LIST **cmdList) { thisSet->bracketDepth >= thisDepth) { /* Loop through all entries on the same line */ - WCHAR *item; + WCHAR *staticitem; WCHAR *itemStart; WCHAR buffer[MAXSTRING]; WINE_TRACE("Processing for set %p\n", thisSet); i = 0; - while (*(item = WCMD_parameter (thisSet->command, i, &itemStart, TRUE, FALSE))) { + while (*(staticitem = WCMD_parameter (thisSet->command, i, &itemStart, TRUE, FALSE))) { /* * If the parameter within the set has a wildcard then search for matching files * otherwise do a literal substitution. */ static const WCHAR wildcards[] = {'*','?','\0'}; + + /* Take a copy of the item returned from WCMD_parameter as it is held in a + static buffer which can be overwritten during parsing of the for body */ + WCHAR item[MAXSTRING]; + strcpyW(item, staticitem); + thisCmdStart = cmdStart; itemNum++; diff --git a/programs/cmd/tests/test_builtins.cmd b/programs/cmd/tests/test_builtins.cmd index d6edc5fff1c..6f2ef4a8435 100644 --- a/programs/cmd/tests/test_builtins.cmd +++ b/programs/cmd/tests/test_builtins.cmd @@ -1155,9 +1155,16 @@ mkdir foobar & cd foobar mkdir foo mkdir bar mkdir baz +mkdir pop echo > bazbaz echo --- basic wildcards for %%i in (ba*) do echo %%i +echo --- wildcards in subdirs +echo something>pop\bar1 +echo something>pop\bar2.txt +echo something>pop\bar3 +for %%f in (pop\ba*) do ( call echo %%f ) +rmdir /s/q pop echo --- for /d for /d %%i in (baz foo bar) do echo %%i 2>&1 rem Confirm we don't match files: diff --git a/programs/cmd/tests/test_builtins.cmd.exp b/programs/cmd/tests/test_builtins.cmd.exp index 22d83c3b192..0eb5b966e88 100644 --- a/programs/cmd/tests/test_builtins.cmd.exp +++ b/programs/cmd/tests/test_builtins.cmd.exp @@ -917,6 +917,10 @@ B C B D --- basic wildcards bazbaz +--- wildcards in subdirs +pop\bar1@space@ +pop\bar2.txt@space@ +pop\bar3@space@ --- for /d baz@space@ foo@space@