aboutsummaryrefslogtreecommitdiff
path: root/shell/hush.c
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2024-10-07 22:00:16 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2024-10-07 22:00:16 +0200
commit8c4bccb83e5e2594f16310b7cbe07bf05fc9f13a (patch)
tree947f48fbf7f19479d13aa14af0230c69fe370db5 /shell/hush.c
parentbaa49bdc1b7b992bfb8298589cd33c04353c6b57 (diff)
downloadbusybox-w32-8c4bccb83e5e2594f16310b7cbe07bf05fc9f13a.tar.gz
busybox-w32-8c4bccb83e5e2594f16310b7cbe07bf05fc9f13a.tar.bz2
busybox-w32-8c4bccb83e5e2594f16310b7cbe07bf05fc9f13a.zip
hush: fix "type ./cat" and "command -v ./cat" to not scan PATH
function old new delta find_executable_in_PATH - 67 +67 if_command_vV_print_and_exit 114 116 +2 .rodata 105712 105710 -2 builtin_type 137 128 -9 ------------------------------------------------------------------------------ (add/remove: 1/0 grow/shrink: 1/2 up/down: 69/-11) Total: 58 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'shell/hush.c')
-rw-r--r--shell/hush.c46
1 files changed, 33 insertions, 13 deletions
diff --git a/shell/hush.c b/shell/hush.c
index 074f35f2b..4e477d05a 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -8201,27 +8201,29 @@ static int setup_redirects(struct command *prog, struct squirrel **sqp)
8201 return 0; 8201 return 0;
8202} 8202}
8203 8203
8204/* Find a file in PATH, not necessarily executable */ 8204/* Find a file in PATH, not necessarily executable
8205 * Name is known to not contain '/'.
8206 */
8205//TODO: shares code with find_executable() in libbb, factor out? 8207//TODO: shares code with find_executable() in libbb, factor out?
8206static char *find_in_path(const char *arg) 8208static char *find_in_PATH(const char *name)
8207{ 8209{
8208 char *ret = NULL; 8210 char *ret;
8209 const char *PATH = get_local_var_value("PATH"); 8211 const char *PATH = get_local_var_value("PATH");
8210 8212
8211 if (!PATH) 8213 if (!PATH)
8212 return NULL; 8214 return NULL;
8213 8215 ret = NULL;
8214 while (1) { 8216 while (1) {
8215 const char *end = strchrnul(PATH, ':'); 8217 const char *end = strchrnul(PATH, ':');
8216 int sz = end - PATH; /* must be int! */ 8218 int sz = end - PATH; /* must be int! */
8217 8219
8218 free(ret); 8220 free(ret);
8219 if (sz != 0) { 8221 if (sz != 0) {
8220 ret = xasprintf("%.*s/%s", sz, PATH, arg); 8222 ret = xasprintf("%.*s/%s", sz, PATH, name);
8221 } else { 8223 } else {
8222 /* We have xxx::yyyy in $PATH, 8224 /* We have xxx::yyyy in $PATH,
8223 * it means "use current dir" */ 8225 * it means "use current dir" */
8224 ret = xstrdup(arg); 8226 ret = xstrdup(name);
8225 } 8227 }
8226 if (access(ret, F_OK) == 0) 8228 if (access(ret, F_OK) == 0)
8227 break; 8229 break;
@@ -8236,6 +8238,24 @@ static char *find_in_path(const char *arg)
8236 return ret; 8238 return ret;
8237} 8239}
8238 8240
8241#if ENABLE_HUSH_TYPE || ENABLE_HUSH_COMMAND
8242static char *find_executable_in_PATH(const char *name)
8243{
8244 char *PATH;
8245 if (strchr(name, '/')) {
8246 /* Name with '/' is tested verbatim, with no PATH traversal:
8247 * "cd /bin; type ./cat" should print "./cat is ./cat",
8248 * NOT "./cat is /bin/./cat"
8249 */
8250 if (file_is_executable(name))
8251 return xstrdup(name);
8252 return NULL;
8253 }
8254 PATH = (char*)get_local_var_value("PATH");
8255 return find_executable(name, &PATH); /* path == NULL is ok */
8256}
8257#endif
8258
8239static const struct built_in_command *find_builtin_helper(const char *name, 8259static const struct built_in_command *find_builtin_helper(const char *name,
8240 const struct built_in_command *x, 8260 const struct built_in_command *x,
8241 const struct built_in_command *end) 8261 const struct built_in_command *end)
@@ -8645,10 +8665,11 @@ static void if_command_vV_print_and_exit(char opt_vV, char *cmd, const char *exp
8645 8665
8646 to_free = NULL; 8666 to_free = NULL;
8647 if (!explanation) { 8667 if (!explanation) {
8648 char *path = (char*)get_local_var_value("PATH"); 8668 explanation = to_free = find_executable_in_PATH(cmd);
8649 explanation = to_free = find_executable(cmd, &path); /* path == NULL is ok */ 8669 if (!explanation) {
8650 if (!explanation) 8670 bb_error_msg("%s: %s: not found", "command", cmd);
8651 _exit(1); /* PROG was not found */ 8671 _exit(1); /* PROG was not found */
8672 }
8652 if (opt_vV != 'V') 8673 if (opt_vV != 'V')
8653 cmd = to_free; /* -v PROG prints "/path/to/PROG" */ 8674 cmd = to_free; /* -v PROG prints "/path/to/PROG" */
8654 } 8675 }
@@ -11075,12 +11096,11 @@ static int FAST_FUNC builtin_type(char **argv)
11075 else if (find_builtin(*argv)) 11096 else if (find_builtin(*argv))
11076 type = "a shell builtin"; 11097 type = "a shell builtin";
11077 else { 11098 else {
11078 char *pathvar = (char*)get_local_var_value("PATH"); 11099 path = find_executable_in_PATH(*argv);
11079 path = find_executable(*argv, &pathvar);
11080 if (path) 11100 if (path)
11081 type = path; 11101 type = path;
11082 else { 11102 else {
11083 bb_error_msg("type: %s: not found", *argv); 11103 bb_error_msg("%s: %s: not found", "type", *argv);
11084 ret = EXIT_FAILURE; 11104 ret = EXIT_FAILURE;
11085 continue; 11105 continue;
11086 } 11106 }
@@ -11710,7 +11730,7 @@ static int FAST_FUNC builtin_source(char **argv)
11710 } 11730 }
11711 arg_path = NULL; 11731 arg_path = NULL;
11712 if (!strchr(filename, '/')) { 11732 if (!strchr(filename, '/')) {
11713 arg_path = find_in_path(filename); 11733 arg_path = find_in_PATH(filename);
11714 if (arg_path) 11734 if (arg_path)
11715 filename = arg_path; 11735 filename = arg_path;
11716 else if (!ENABLE_HUSH_BASH_SOURCE_CURDIR) { 11736 else if (!ENABLE_HUSH_BASH_SOURCE_CURDIR) {