cmd: Avoid infinite loop running batch program.

This commit is contained in:
Jason Edmeades 2013-06-04 21:27:48 +01:00 committed by Alexandre Julliard
parent a5b1172e90
commit dd0b719a3a
3 changed files with 13 additions and 17 deletions

View file

@ -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

View file

@ -70,6 +70,7 @@ var=33@space@
0@space@
3@space@
4@space@
Passed
---------- Testing CMD /C quoting -----------------
"hi"
1@space@

View file

@ -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;