From: Bram Moolenaar Date: Sat, 6 Oct 2018 13:18:45 +0000 (+0200) Subject: patch 8.1.0453: MS-Windows: executable() is not reliable X-Git-Tag: v8.1.0453 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8295666dc2c65e42135b91d5c61e2a140d002333;p=vim patch 8.1.0453: MS-Windows: executable() is not reliable Problem: MS-Windows: executable() is not reliable. Solution: Use $PATHEXT properly. (Yasuhiro Matsumoto, closes #3412) --- diff --git a/src/os_win32.c b/src/os_win32.c index 4ba060bb9..9d1d8cbc2 100644 --- a/src/os_win32.c +++ b/src/os_win32.c @@ -3535,21 +3535,44 @@ mch_can_exe(char_u *name, char_u **path, int use_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 index cc82f8191..17f7c1905 100644 --- 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 index b50ce81aa..dee74d3e0 100644 --- a/src/version.c +++ b/src/version.c @@ -792,6 +792,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 453, /**/ 452, /**/