changeset 14883:1c2ba2b0227e v8.1.0453

patch 8.1.0453: MS-Windows: executable() is not reliable commit https://github.com/vim/vim/commit/8295666dc2c65e42135b91d5c61e2a140d002333 Author: Bram Moolenaar <Bram@vim.org> Date: Sat Oct 6 15:18:45 2018 +0200 patch 8.1.0453: MS-Windows: executable() is not reliable Problem: MS-Windows: executable() is not reliable. Solution: Use $PATHEXT properly. (Yasuhiro Matsumoto, closes https://github.com/vim/vim/issues/3412)
author Bram Moolenaar <Bram@vim.org>
date Sat, 06 Oct 2018 15:30:06 +0200
parents 32c08beec8c9
children dda717e7b164
files src/os_win32.c src/testdir/test_functions.vim src/version.c
diffstat 3 files changed, 43 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/src/os_win32.c
+++ b/src/os_win32.c
@@ -3535,21 +3535,44 @@ mch_can_exe(char_u *name, char_u **path,
 {
     char_u	buf[_MAX_PATH];
     int		len = (int)STRLEN(name);
-    char_u	*p;
+    char_u	*p, *saved;
 
     if (len >= _MAX_PATH)	/* safety check */
 	return FALSE;
 
-    /* If there already is an extension try using the name directly.  Also do
-     * this with a Unix-shell like 'shell'. */
-    if (vim_strchr(gettail(name), '.') != NULL
-			       || strstr((char *)gettail(p_sh), "sh") != NULL)
+    /* Ty using the name directly when a Unix-shell like 'shell'. */
+    if (strstr((char *)gettail(p_sh), "sh") != NULL)
 	if (executable_exists((char *)name, path, use_path))
 	    return TRUE;
 
     /*
      * Loop over all extensions in $PATHEXT.
      */
+    p = mch_getenv("PATHEXT");
+    if (p == NULL)
+	p = (char_u *)".com;.exe;.bat;.cmd";
+    saved = vim_strsave(p);
+    if (saved == NULL)
+	return FALSE;
+    p = saved;
+    while (*p)
+    {
+	char_u	*tmp = vim_strchr(p, ';');
+
+	if (tmp != NULL)
+	    *tmp = NUL;
+	if (_stricoll((char *)name + len - STRLEN(p), (char *)p) == 0
+			    && executable_exists((char *)name, path, use_path))
+	{
+	    vim_free(saved);
+	    return TRUE;
+	}
+	if (tmp == NULL)
+	    break;
+	p = tmp + 1;
+    }
+    vim_free(saved);
+
     vim_strncpy(buf, name, _MAX_PATH - 1);
     p = mch_getenv("PATHEXT");
     if (p == NULL)
--- a/src/testdir/test_functions.vim
+++ b/src/testdir/test_functions.vim
@@ -800,6 +800,19 @@ func Test_filewritable()
   bw!
 endfunc
 
+func Test_Executable()
+  if has('win32')
+    call assert_equal(1, executable('notepad'))
+    call assert_equal(1, executable('notepad.exe'))
+    call assert_equal(0, executable('notepad.exe.exe'))
+    call assert_equal(0, executable('shell32.dll'))
+    call assert_equal(0, executable('win.ini'))
+  elseif has('unix')
+    call assert_equal(1, executable('cat'))
+    call assert_equal(0, executable('dog'))
+  endif
+endfunc
+
 func Test_hostname()
   let hostname_vim = hostname()
   if has('unix')
--- a/src/version.c
+++ b/src/version.c
@@ -793,6 +793,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    453,
+/**/
     452,
 /**/
     451,