(cc-ing the reporter) Brandon Williams wrote: > In some situations run-command will incorrectly try (and fail) to > execute a directory instead of an executable. For example: > > Lets suppose a user has PATH=~/bin (where 'bin' is a directory) and they > happen to have another directory inside 'bin' named 'git-remote-blah'. > Then git tries to execute the directory: > > $ git ls-remote blah://blah > fatal: cannot exec 'git-remote-blah': Permission denied > > This is due to only checking 'access()' when locating an executable in > PATH, which doesn't distinguish between files and directories. Instead > use 'stat()' and check that the path is to a regular file. Now > run-command won't try to execute the directory 'git-remote-blah': > > $ git ls-remote blah://blah > fatal: Unable to find remote helper for 'blah' Reported-by: Brian Hatfield <bhatfield@xxxxxxxxxx> This was observed by having a directory called "ssh" in $PATH before the real ssh and trying to use ssh protoccol. Thanks for catching it. > Signed-off-by: Brandon Williams <bmwill@xxxxxxxxxx> > --- > run-command.c | 3 ++- > t/t0061-run-command.sh | 7 +++++++ > 2 files changed, 9 insertions(+), 1 deletion(-) > > diff --git a/run-command.c b/run-command.c > index a97d7bf9f..ece0bf342 100644 > --- a/run-command.c > +++ b/run-command.c > @@ -127,6 +127,7 @@ static char *locate_in_PATH(const char *file) > > while (1) { > const char *end = strchrnul(p, ':'); > + struct stat st; > > strbuf_reset(&buf); > > @@ -137,7 +138,7 @@ static char *locate_in_PATH(const char *file) > } > strbuf_addstr(&buf, file); > > - if (!access(buf.buf, F_OK)) > + if (!stat(buf.buf, &st) && S_ISREG(st.st_mode)) > return strbuf_detach(&buf, NULL); > > if (!*end) > diff --git a/t/t0061-run-command.sh b/t/t0061-run-command.sh > index 98c09dd98..30c4ad75f 100755 > --- a/t/t0061-run-command.sh > +++ b/t/t0061-run-command.sh > @@ -37,6 +37,13 @@ test_expect_success !MINGW 'run_command can run a script without a #! line' ' > test_cmp empty err > ' > > +test_expect_success 'run_command should not try to execute a directory' ' > + test_when_finished "rm -rf bin/blah" && > + mkdir -p bin/blah && > + PATH=bin:$PATH test_must_fail test-run-command run-command blah 2>err && > + test_i18ngrep "No such file or directory" err > +' > + > test_expect_success POSIXPERM 'run_command reports EACCES' ' > cat hello-script >hello.sh && > chmod -x hello.sh &&