From 6e6abd0cdfe4bb96f6412aebc511f10bf254a820 Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Sat, 23 May 2020 12:19:34 +0200 Subject: [PATCH] findprog-in: Ignore directories. Reported by Frederick Eaton via Dmitry Goncharov in . * lib/findprog-in.c (find_in_given_path): When the file found is a directory, set errno to EACCES and, during a PATH search, continue searching. * modules/findprog-in (Depends-on): Add sys_stat, stat. --- ChangeLog | 10 ++++++ lib/findprog-in.c | 75 ++++++++++++++++++++++++++++++--------------- modules/findprog-in | 2 ++ 3 files changed, 62 insertions(+), 25 deletions(-) diff --git a/ChangeLog b/ChangeLog index 44450a3549..b22d791c60 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2020-05-23 Bruno Haible + + findprog-in: Ignore directories. + Reported by Frederick Eaton via Dmitry Goncharov in + . + * lib/findprog-in.c (find_in_given_path): When the file found is a + directory, set errno to EACCES and, during a PATH search, continue + searching. + * modules/findprog-in (Depends-on): Add sys_stat, stat. + 2020-05-23 Paul Eggert verify: document ‘assume’ better diff --git a/lib/findprog-in.c b/lib/findprog-in.c index c254f2f588..0f76e36ca4 100644 --- a/lib/findprog-in.c +++ b/lib/findprog-in.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "filename.h" #include "concat-filename.h" @@ -58,8 +59,8 @@ static const char * const suffixes[] = /* Note: The cmd.exe program does a different lookup: It searches according to the PATHEXT environment variable. See . - Also, it executes files ending .bat and .cmd directly without letting the - kernel interpret the program file. */ + Also, it executes files ending in .bat and .cmd directly without letting + the kernel interpret the program file. */ #elif defined __CYGWIN__ "", ".exe", ".com" #elif defined __EMX__ @@ -136,14 +137,26 @@ find_in_given_path (const char *progname, const char *path, call access() despite its design flaw. */ if (eaccess (progpathname, X_OK) == 0) { - /* Found! */ - if (strcmp (progpathname, progname) == 0) + /* Check that the progpathname does not point to a + directory. */ + struct stat statbuf; + + if (stat (progpathname, &statbuf) >= 0) { - free (progpathname); - return progname; + if (! S_ISDIR (statbuf.st_mode)) + { + /* Found! */ + if (strcmp (progpathname, progname) == 0) + { + free (progpathname); + return progname; + } + else + return progpathname; + } + + errno = EACCES; } - else - return progpathname; } if (errno != ENOENT) @@ -210,25 +223,37 @@ find_in_given_path (const char *progname, const char *path, call access() despite its design flaw. */ if (eaccess (progpathname, X_OK) == 0) { - /* Found! */ - if (strcmp (progpathname, progname) == 0) + /* Check that the progpathname does not point to a + directory. */ + struct stat statbuf; + + if (stat (progpathname, &statbuf) >= 0) { - free (progpathname); - - /* Add the "./" prefix for real, that - xconcatenated_filename() optimized away. This - avoids a second PATH search when the caller uses - execl/execv/execlp/execvp. */ - progpathname = - XNMALLOC (2 + strlen (progname) + 1, char); - progpathname[0] = '.'; - progpathname[1] = NATIVE_SLASH; - memcpy (progpathname + 2, progname, - strlen (progname) + 1); - } + if (! S_ISDIR (statbuf.st_mode)) + { + /* Found! */ + if (strcmp (progpathname, progname) == 0) + { + free (progpathname); + + /* Add the "./" prefix for real, that + xconcatenated_filename() optimized away. + This avoids a second PATH search when the + caller uses execl/execv/execlp/execvp. */ + progpathname = + XNMALLOC (2 + strlen (progname) + 1, char); + progpathname[0] = '.'; + progpathname[1] = NATIVE_SLASH; + memcpy (progpathname + 2, progname, + strlen (progname) + 1); + } + + free (path_copy); + return progpathname; + } - free (path_copy); - return progpathname; + errno = EACCES; + } } if (errno != ENOENT) diff --git a/modules/findprog-in b/modules/findprog-in index 971366b83a..84787a644e 100644 --- a/modules/findprog-in +++ b/modules/findprog-in @@ -9,10 +9,12 @@ m4/eaccess.m4 Depends-on: stdbool +sys_stat filename xalloc xconcat-filename access +stat unistd configure.ac: -- 2.39.5