@@ -611,6 +611,18 @@ bool git_fs_path_isfile(const char *path)
611611 return S_ISREG (st .st_mode ) != 0 ;
612612}
613613
614+ bool git_fs_path_isexecutable (const char * path )
615+ {
616+ struct stat st ;
617+
618+ GIT_ASSERT_ARG_WITH_RETVAL (path , false);
619+ if (p_stat (path , & st ) < 0 )
620+ return false;
621+
622+ return S_ISREG (st .st_mode ) != 0 &&
623+ ((st .st_mode & S_IXUSR ) != 0 );
624+ }
625+
614626bool git_fs_path_islink (const char * path )
615627{
616628 struct stat st ;
@@ -2038,8 +2050,17 @@ int git_fs_path_find_executable(git_str *fullpath, const char *executable)
20382050#else
20392051 git_str path = GIT_STR_INIT ;
20402052 const char * current_dir , * term ;
2053+ size_t current_dirlen ;
20412054 bool found = false;
20422055
2056+ /* For qualified paths we do not look in PATH */
2057+ if (strchr (executable , '/' ) != NULL ) {
2058+ if (!git_fs_path_isexecutable (executable ))
2059+ return GIT_ENOTFOUND ;
2060+
2061+ return git_str_puts (fullpath , executable );
2062+ }
2063+
20432064 if (git__getenv (& path , "PATH" ) < 0 )
20442065 return -1 ;
20452066
@@ -2049,20 +2070,28 @@ int git_fs_path_find_executable(git_str *fullpath, const char *executable)
20492070 if (! (term = strchr (current_dir , GIT_PATH_LIST_SEPARATOR )))
20502071 term = strchr (current_dir , '\0' );
20512072
2073+ current_dirlen = term - current_dir ;
20522074 git_str_clear (fullpath );
2053- if (git_str_put (fullpath , current_dir , (term - current_dir )) < 0 ||
2054- git_str_putc (fullpath , '/' ) < 0 ||
2075+
2076+ /* An empty path segment is treated as '.' */
2077+ if (current_dirlen == 0 && git_str_putc (fullpath , '.' ))
2078+ return -1 ;
2079+ else if (current_dirlen != 0 &&
2080+ git_str_put (fullpath , current_dir , current_dirlen ) < 0 )
2081+ return -1 ;
2082+
2083+ if (git_str_putc (fullpath , '/' ) < 0 ||
20552084 git_str_puts (fullpath , executable ) < 0 )
20562085 return -1 ;
20572086
2058- if (git_fs_path_isfile (fullpath -> ptr )) {
2087+ if (git_fs_path_isexecutable (fullpath -> ptr )) {
20592088 found = true;
20602089 break ;
20612090 }
20622091
20632092 current_dir = term ;
20642093
2065- while (* current_dir == GIT_PATH_LIST_SEPARATOR )
2094+ if (* current_dir == GIT_PATH_LIST_SEPARATOR )
20662095 current_dir ++ ;
20672096 }
20682097
0 commit comments