Skip to content

Commit bd686d8

Browse files
koronchrisbra
authored andcommitted
patch 9.1.2004: MS-Windows: executable() cannot find file in directory with single char
Problem: MS-Windows: If a directory with a single character name is included in the PATH environment variable without a trailing path separator, executable() will not be able to find the executable file under it. Solution: The second argument of the after_pathsep() function is now passed the next pointer where a path separator may exist (Muraoka Taro). As a specific example, the default installation path for PowerShell v7 is "C:\Program Files\PowerShell\7", but if you set this as is in the PATH environment variable, Vim will not be able to find the pwsh.exe command. In this case, Vim will try to search for "C:\Program Files\PowerShell\7pwsh.exe". Cause: The after_pathsep() function determines whether the location passed as its second argument immediately follows a path separator. However, in the code where the problem occurred, the second argument was passed a location that might contain a path separator. As a result, it was mistakenly determined that a path separator was present in cases where the final directory name was a single character and not followed by a path separator, and the path to search was incorrect. closes: #18979 Signed-off-by: Muraoka Taro <koron.kaoriya@gmail.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
1 parent e09ff34 commit bd686d8

3 files changed

Lines changed: 38 additions & 1 deletion

File tree

src/os_win32.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2920,7 +2920,7 @@ executable_exists(
29202920
(char *)buf,
29212921
sizeof(buf),
29222922
"%.*s%s%s", (int)(e - p), p,
2923-
!after_pathsep(p, e - 1) ? PATHSEPSTR : "",
2923+
!after_pathsep(p, e) ? PATHSEPSTR : "",
29242924
name);
29252925
}
29262926

src/testdir/test_functions.vim

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2140,6 +2140,41 @@ func Test_executable_longname()
21402140
call delete(fname)
21412141
endfunc
21422142

2143+
func Test_executable_single_character_dir()
2144+
call mkdir('Xpath', 'R')
2145+
call mkdir('Xpath/a')
2146+
call mkdir('Xpath/b')
2147+
call mkdir('Xpath/c')
2148+
if has('win32')
2149+
call writefile([], 'Xpath/a/Xcmd1.bat')
2150+
call writefile([], 'Xpath/b/Xcmd2.bat')
2151+
call writefile([], 'Xpath/c/Xcmd3.bat')
2152+
let sep = ';'
2153+
else
2154+
call writefile([], 'Xpath/a/Xcmd1')
2155+
call writefile([], 'Xpath/b/Xcmd2')
2156+
call writefile([], 'Xpath/c/Xcmd3')
2157+
call setfperm('Xpath/a/Xcmd1', 'rwxr-xr-x')
2158+
call setfperm('Xpath/b/Xcmd2', 'rwxr-xr-x')
2159+
call setfperm('Xpath/c/Xcmd3', 'rwxr-xr-x')
2160+
let sep = ':'
2161+
endif
2162+
2163+
let save_path = $PATH
2164+
" a: single character name without path seperator
2165+
" b: single character name with path seperator
2166+
" c: single character name without path seperator at last of PATH
2167+
let $PATH = [
2168+
\ fnamemodify('./Xpath/a', ':p:h'),
2169+
\ fnamemodify('./Xpath/b', ':p'),
2170+
\ fnamemodify('./Xpath/c', ':p:h')
2171+
\ ]->join(sep)
2172+
call assert_true(executable('Xcmd1'))
2173+
call assert_true(executable('Xcmd2'))
2174+
call assert_true(executable('Xcmd3'))
2175+
let $PATH = save_path
2176+
endfunc
2177+
21432178
func Test_hostname()
21442179
let hostname_vim = hostname()
21452180
if has('unix')

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -734,6 +734,8 @@ static char *(features[]) =
734734

735735
static int included_patches[] =
736736
{ /* Add new patch number below this line */
737+
/**/
738+
2004,
737739
/**/
738740
2003,
739741
/**/

0 commit comments

Comments
 (0)