diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2024-10-07 22:00:16 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2024-10-07 22:00:16 +0200 |
commit | 8c4bccb83e5e2594f16310b7cbe07bf05fc9f13a (patch) | |
tree | 947f48fbf7f19479d13aa14af0230c69fe370db5 /shell/hush.c | |
parent | baa49bdc1b7b992bfb8298589cd33c04353c6b57 (diff) | |
download | busybox-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.c | 46 |
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? |
8206 | static char *find_in_path(const char *arg) | 8208 | static 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 | ||
8242 | static 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 | |||
8239 | static const struct built_in_command *find_builtin_helper(const char *name, | 8259 | static 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) { |