Jason Edmeades : cmd: Avoid infinite loop running batch program.
Alexandre Julliard
julliard at winehq.org
Wed Jun 5 13:47:02 CDT 2013
Module: wine
Branch: master
Commit: dd0b719a3a1419f34774fc4cd921f3378d8c237b
URL: http://source.winehq.org/git/wine.git/?a=commit;h=dd0b719a3a1419f34774fc4cd921f3378d8c237b
Author: Jason Edmeades <jason at edmeades.me.uk>
Date: Tue Jun 4 21:27:48 2013 +0100
cmd: Avoid infinite loop running batch program.
---
programs/cmd/tests/test_cmdline.cmd | 8 +++++++-
programs/cmd/tests/test_cmdline.cmd.exp | 1 +
programs/cmd/wcmdmain.c | 21 +++++----------------
3 files changed, 13 insertions(+), 17 deletions(-)
diff --git a/programs/cmd/tests/test_cmdline.cmd b/programs/cmd/tests/test_cmdline.cmd
index e563341..32a1ef2 100644
--- a/programs/cmd/tests/test_cmdline.cmd
+++ b/programs/cmd/tests/test_cmdline.cmd
@@ -95,6 +95,7 @@ echo @echo 1 > "say one.bat"
echo @echo 2 > "saytwo.bat"
echo @echo 3 > "say (3).bat"
echo @echo 4 > "say .bat"
+echo @echo 5 > "bazbaz(5).bat"
echo ------ Testing invocation of batch files ----------
call say one
@@ -144,6 +145,11 @@ if errorlevel 2 echo error %ErrorLevel%
call :setError 0
cmd /c say" "(3) prints 4?!
if errorlevel 2 echo error %ErrorLevel%
+call :setError 0
+rem Deliberately invoking a fully qualified batch name containing a bracket
+rem should fail, as a bracket is a command delimiter.
+cmd /c "bazbaz(5).bat"
+if errorlevel 1 echo Passed
echo ---------- Testing CMD /C quoting -----------------
cmd /c @echo "hi"
@@ -261,7 +267,7 @@ call tell(1234)
call tell(12(34)
call tell(12;34)
echo --------- Finished --------------
-del tell.bat say*.*
+del tell.bat say*.* bazbaz*.bat
exit
:setError
exit /B %1
diff --git a/programs/cmd/tests/test_cmdline.cmd.exp b/programs/cmd/tests/test_cmdline.cmd.exp
index 38e17a5..980f674 100644
--- a/programs/cmd/tests/test_cmdline.cmd.exp
+++ b/programs/cmd/tests/test_cmdline.cmd.exp
@@ -70,6 +70,7 @@ var=33 at space@
0 at space@
3 at space@
4 at space@
+Passed
---------- Testing CMD /C quoting -----------------
"hi"
1 at space@
diff --git a/programs/cmd/wcmdmain.c b/programs/cmd/wcmdmain.c
index 0d4575b..a211efa 100644
--- a/programs/cmd/wcmdmain.c
+++ b/programs/cmd/wcmdmain.c
@@ -1048,7 +1048,6 @@ void WCMD_run_program (WCHAR *command, BOOL called)
BOOL extensionsupplied = FALSE;
BOOL launched = FALSE;
BOOL status;
- BOOL assumeInternal = FALSE;
DWORD len;
static const WCHAR envPath[] = {'P','A','T','H','\0'};
static const WCHAR delims[] = {'/','\\',':','\0'};
@@ -1168,20 +1167,8 @@ void WCMD_run_program (WCHAR *command, BOOL called)
}
}
- /* Internal programs won't be picked up by this search, so even
- though not found, try one last createprocess and wait for it
- to complete.
- Note: Ideally we could tell between a console app (wait) and a
- windows app, but the API's for it fail in this case */
- if (!found && pathposn == NULL) {
- WINE_TRACE("ASSUMING INTERNAL\n");
- assumeInternal = TRUE;
- } else {
- WINE_TRACE("Found as %s\n", wine_dbgstr_w(thisDir));
- }
-
/* Once found, launch it */
- if (found || assumeInternal) {
+ if (found) {
STARTUPINFOW st;
PROCESS_INFORMATION pe;
SHFILEINFOW psfi;
@@ -1191,6 +1178,8 @@ void WCMD_run_program (WCHAR *command, BOOL called)
static const WCHAR batExt[] = {'.','b','a','t','\0'};
static const WCHAR cmdExt[] = {'.','c','m','d','\0'};
+ WINE_TRACE("Found as %s\n", wine_dbgstr_w(thisDir));
+
/* Special case BAT and CMD */
if (ext && (!strcmpiW(ext, batExt) || !strcmpiW(ext, cmdExt))) {
BOOL oldinteractive = interactive;
@@ -1214,7 +1203,7 @@ void WCMD_run_program (WCHAR *command, BOOL called)
/* Launch the process and if a CUI wait on it to complete
Note: Launching internal wine processes cannot specify a full path to exe */
- status = CreateProcessW(assumeInternal?NULL : thisDir,
+ status = CreateProcessW(thisDir,
command, NULL, NULL, TRUE, 0, NULL, NULL, &st, &pe);
heap_free(st.lpReserved2);
if ((opt_c || opt_k) && !opt_s && !status
@@ -1231,7 +1220,7 @@ void WCMD_run_program (WCHAR *command, BOOL called)
/* Always wait when non-interactive (cmd /c or in batch program),
or for console applications */
- if (assumeInternal || !interactive || (console && !HIWORD(console)))
+ if (!interactive || (console && !HIWORD(console)))
WaitForSingleObject (pe.hProcess, INFINITE);
GetExitCodeProcess (pe.hProcess, &errorlevel);
if (errorlevel == STILL_ACTIVE) errorlevel = 0;
More information about the wine-cvs
mailing list