From bde1bbf224f90b5ca4cfddad918e3a096a6c3a05 Mon Sep 17 00:00:00 2001 From: Fabian Maurer Date: Thu, 2 Aug 2018 19:48:59 +0200 Subject: [PATCH] cmd: Handle quotes when parsing the folders in the PATH environment variable Semicolons are also allowed inside a path, as long as they are quoted. Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=45552 Signed-off-by: Fabian Maurer --- programs/cmd/tests/test_builtins.cmd | 17 +++++++++++++++++ programs/cmd/tests/test_builtins.cmd.exp | 3 +++ programs/cmd/wcmdmain.c | 27 ++++++++++++++++++++++----- 3 files changed, 42 insertions(+), 5 deletions(-) diff --git a/programs/cmd/tests/test_builtins.cmd b/programs/cmd/tests/test_builtins.cmd index b9e9b25..775f21b 100644 --- a/programs/cmd/tests/test_builtins.cmd +++ b/programs/cmd/tests/test_builtins.cmd @@ -507,6 +507,23 @@ rem Only the final quote ends the string set "WINE_FOO=apple"banana"grape"orange echo '%WINE_FOO%' set WINE_FOO= +rem set PATH must work with quotes +set PATH_BACKUP=%PATH% +mkdir folder +mkdir "fol;der" +echo echo I'm here! > "fol;der\sub1.bat" +echo echo I'm here! > folder\sub1.bat +set PATH=nothing;"fol;der" +call sub1 +set PATH="folder +call sub1 +set PATH=folder" +call sub1 +del "fol;der\sub1.bat" +del folder\sub1.bat +rmdir "fol;der" +rmdir folder +PATH=%PATH_BACKUP% echo ------------ Testing variable expansion ------------ call :setError 0 diff --git a/programs/cmd/tests/test_builtins.cmd.exp b/programs/cmd/tests/test_builtins.cmd.exp index 3118359..ea4157c 100644 --- a/programs/cmd/tests/test_builtins.cmd.exp +++ b/programs/cmd/tests/test_builtins.cmd.exp @@ -475,6 +475,9 @@ foo 'jim fred' 'jim' 'apple"banana"grape' +I'm here!@space@ +I'm here!@space@ +I'm here!@space@ ------------ Testing variable expansion ------------ ~p0 should be path containing batch file @path@ diff --git a/programs/cmd/wcmdmain.c b/programs/cmd/wcmdmain.c index 8fe2d57..5135be4 100644 --- a/programs/cmd/wcmdmain.c +++ b/programs/cmd/wcmdmain.c @@ -1099,24 +1099,41 @@ void WCMD_run_program (WCHAR *command, BOOL called) wine_dbgstr_w(stemofsearch)); while (pathposn) { WCHAR thisDir[MAX_PATH] = {'\0'}; + int length = 0; WCHAR *pos = NULL; BOOL found = FALSE; + BOOL inside_quotes = FALSE; /* Work on the first directory on the search path */ - pos = strchrW(pathposn, ';'); - if (pos) { + pos = pathposn; + while ((inside_quotes || *pos != ';') && *pos != 0) + { + if (*pos == '"') + inside_quotes = !inside_quotes; + pos++; + } + + if (*pos) { /* Reached semicolon */ memcpy(thisDir, pathposn, (pos-pathposn) * sizeof(WCHAR)); thisDir[(pos-pathposn)] = 0x00; pathposn = pos+1; - - } else { + } else { /* Reached string end */ strcpyW(thisDir, pathposn); pathposn = NULL; } + /* Remove quotes */ + length = strlenW(thisDir); + if (thisDir[length - 1] == '"') + thisDir[length - 1] = 0; + + if (*thisDir != '"') + strcpyW(temp, thisDir); + else + strcpyW(temp, thisDir + 1); + /* Since you can have eg. ..\.. on the path, need to expand to full information */ - strcpyW(temp, thisDir); GetFullPathNameW(temp, MAX_PATH, thisDir, NULL); /* 1. If extension supplied, see if that file exists */ -- 1.9.1