# HG changeset patch # User Bram Moolenaar # Date 1538832606 -7200 # Node ID 1c2ba2b0227e103df9317033735450e63f9f3d87 # Parent 32c08beec8c953e280962f5fba1e1c9c575a0347 patch 8.1.0453: MS-Windows: executable() is not reliable commit https://github.com/vim/vim/commit/8295666dc2c65e42135b91d5c61e2a140d002333 Author: Bram Moolenaar 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) diff --git a/src/os_win32.c b/src/os_win32.c --- 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) diff --git a/src/testdir/test_functions.vim b/src/testdir/test_functions.vim --- 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') diff --git a/src/version.c b/src/version.c --- 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,