[2/2] shell32: ShellExecute() should not exec non-executable files.

Francois Gouget fgouget at codeweavers.com
Mon Dec 28 17:44:29 CST 2015


Signed-off-by: Francois Gouget <fgouget at codeweavers.com>
---
 dlls/shell32/shellpath.c     |  2 +-
 dlls/shell32/shlexec.c       | 65 ++++++++++++++++++++++++--------------------
 dlls/shell32/tests/shlexec.c |  4 +--
 3 files changed, 37 insertions(+), 34 deletions(-)

diff --git a/dlls/shell32/shellpath.c b/dlls/shell32/shellpath.c
index cb79d6f..e4c93da 100644
--- a/dlls/shell32/shellpath.c
+++ b/dlls/shell32/shellpath.c
@@ -384,7 +384,7 @@ static BOOL PathIsExeA (LPCSTR lpszPath)
 /*************************************************************************
  *  PathIsExeW		[internal]
  */
-static BOOL PathIsExeW (LPCWSTR lpszPath)
+BOOL PathIsExeW (LPCWSTR lpszPath)
 {
 	LPCWSTR lpszExtension = PathGetExtensionW(lpszPath);
         int i;
diff --git a/dlls/shell32/shlexec.c b/dlls/shell32/shlexec.c
index 5fcbe03..da057fb 100644
--- a/dlls/shell32/shlexec.c
+++ b/dlls/shell32/shlexec.c
@@ -1549,6 +1549,8 @@ static void do_error_dialog( UINT_PTR retval, HWND hwnd )
     MessageBoxW(hwnd, msg, NULL, MB_ICONERROR);
 }
 
+BOOL PathIsExeW(LPCWSTR);
+
 /*************************************************************************
  *	SHELL_execute [Internal]
  */
@@ -1752,40 +1754,43 @@ static BOOL SHELL_execute( LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc )
             sei_tmp.lpDirectory = wszDir;
         }
     }
-
-    /* Else, try to execute the filename */
-    TRACE("execute:%s,%s,%s\n", debugstr_w(wszApplicationName), debugstr_w(wszParameters), debugstr_w(wszDir));
     lpFile = sei_tmp.lpFile;
     wcmd = wcmdBuffer;
-    len = lstrlenW(wszApplicationName) + 3;
-    if (sei_tmp.lpParameters[0])
-        len += 1 + lstrlenW(wszParameters);
-    if (len > wcmdLen)
+
+    if ((sei_tmp.lpVerb && *sei_tmp.lpVerb) || PathIsExeW(wszApplicationName))
     {
-        wcmd = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
-        wcmdLen = len;
-    }
-    wcmd[0] = '\"';
-    len = lstrlenW(wszApplicationName);
-    memcpy(wcmd+1, wszApplicationName, len * sizeof(WCHAR));
-    len++;
-    wcmd[len++] = '\"';
-    wcmd[len] = 0;
-    if (sei_tmp.lpParameters[0]) {
-        wcmd[len++] = ' ';
-        strcpyW(wcmd+len, wszParameters);
-    }
+        /* Else, try to execute the filename */
+        TRACE("execute:%s,%s,%s\n", debugstr_w(wszApplicationName), debugstr_w(wszParameters), debugstr_w(wszDir));
+        len = lstrlenW(wszApplicationName) + 3;
+        if (sei_tmp.lpParameters[0])
+            len += 1 + lstrlenW(wszParameters);
+        if (len > wcmdLen)
+        {
+            wcmd = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+            wcmdLen = len;
+        }
+        wcmd[0] = '\"';
+        len = lstrlenW(wszApplicationName);
+        memcpy(wcmd+1, wszApplicationName, len * sizeof(WCHAR));
+        len++;
+        wcmd[len++] = '\"';
+        wcmd[len] = 0;
+        if (sei_tmp.lpParameters[0]) {
+            wcmd[len++] = ' ';
+            strcpyW(wcmd+len, wszParameters);
+        }
 
-    retval = execfunc(wcmd, NULL, FALSE, &sei_tmp, sei);
-    if (retval > 32) {
-        HeapFree(GetProcessHeap(), 0, wszApplicationName);
-        if (wszParameters != parametersBuffer)
-            HeapFree(GetProcessHeap(), 0, wszParameters);
-        if (wszDir != dirBuffer)
-            HeapFree(GetProcessHeap(), 0, wszDir);
-        if (wcmd != wcmdBuffer)
-            HeapFree(GetProcessHeap(), 0, wcmd);
-        return TRUE;
+        retval = execfunc(wcmd, NULL, FALSE, &sei_tmp, sei);
+        if (retval > 32) {
+            HeapFree(GetProcessHeap(), 0, wszApplicationName);
+            if (wszParameters != parametersBuffer)
+                HeapFree(GetProcessHeap(), 0, wszParameters);
+            if (wszDir != dirBuffer)
+                HeapFree(GetProcessHeap(), 0, wszDir);
+            if (wcmd != wcmdBuffer)
+                HeapFree(GetProcessHeap(), 0, wcmd);
+            return TRUE;
+        }
     }
 
     /* Else, try to find the executable */
diff --git a/dlls/shell32/tests/shlexec.c b/dlls/shell32/tests/shlexec.c
index 0a041fa..d080255 100644
--- a/dlls/shell32/tests/shlexec.c
+++ b/dlls/shell32/tests/shlexec.c
@@ -2108,9 +2108,7 @@ static void test_exes(void)
         if (CopyFileA(argv0, filename, FALSE))
         {
             rc=shell_execute(NULL, filename, params, NULL);
-            todo_wine {
-                ok(rc==SE_ERR_NOASSOC, "%s succeeded: rc=%lu\n", shell_call, rc);
-            }
+            ok(rc==SE_ERR_NOASSOC, "%s succeeded: rc=%lu\n", shell_call, rc);
         }
     }
     else
-- 
2.6.4



More information about the wine-patches mailing list