From 04129e0bde3c2d25ab676079e6e3b6fdcdeabe4f Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Sun, 24 May 2020 10:27:23 +0100 Subject: win32: changes to '#!' support Since the earliest days of busybox-w32 '#!' has searched PATH for the interpreter. This doesn't seem to be supported by precedent. In testing I also found that additional code was needed for the case where PATH has been altered in the current shell or is modified on the command line: PATH has to be extracted from envp rather than getenv("PATH"). Drop this non-standard feature. *NIX implementations disagree on whether the interpreter can itself be a script. Follow Linux and allow this with a limit of four levels of nesting. --- win32/process.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) (limited to 'win32') diff --git a/win32/process.c b/win32/process.c index 28df33c23..d33f06405 100644 --- a/win32/process.c +++ b/win32/process.c @@ -292,7 +292,8 @@ mingw_spawn_applet(int mode, #endif static intptr_t -mingw_spawn_interpreter(int mode, const char *prog, char *const *argv, char *const *envp) +mingw_spawn_interpreter(int mode, const char *prog, char *const *argv, + char *const *envp, int level) { intptr_t ret; int nopts; @@ -304,6 +305,11 @@ mingw_spawn_interpreter(int mode, const char *prog, char *const *argv, char *con if (!parse_interpreter(prog, &interp)) return spawnveq(mode, prog, argv, envp); + if (++level > 4) { + errno = ELOOP; + return -1; + } + nopts = interp.opts != NULL; argc = string_array_len((char **)argv); new_argv = xmalloc(sizeof(*argv)*(argc+nopts+2)); @@ -314,7 +320,7 @@ mingw_spawn_interpreter(int mode, const char *prog, char *const *argv, char *con if ((fullpath=alloc_win32_extension(interp.path)) != NULL || file_is_executable(interp.path)) { new_argv[0] = fullpath ? fullpath : interp.path; - ret = spawnveq(mode, new_argv[0], new_argv, envp); + ret = mingw_spawn_interpreter(mode, new_argv[0], new_argv, envp, level); } else #if ENABLE_FEATURE_PREFER_APPLETS || ENABLE_FEATURE_SH_STANDALONE if (find_applet_by_name(interp.name) >= 0) { @@ -323,11 +329,7 @@ mingw_spawn_interpreter(int mode, const char *prog, char *const *argv, char *con ret = mingw_spawn_applet(mode, new_argv, envp); } else #endif - if ((fullpath=find_first_executable(interp.name)) != NULL) { - new_argv[0] = fullpath; - ret = spawnveq(mode, fullpath, new_argv, envp); - } - else { + { errno = ENOENT; ret = -1; } @@ -349,10 +351,10 @@ mingw_spawn_1(int mode, const char *cmd, char *const *argv, char *const *envp) #endif if (strchr(cmd, '/') || strchr(cmd, '\\') || has_dos_drive_prefix(cmd)) { const char *path = auto_win32_extension(cmd); - return mingw_spawn_interpreter(mode, path ? path : cmd, argv, envp); + return mingw_spawn_interpreter(mode, path ? path : cmd, argv, envp, 0); } else if ((prog=find_first_executable(cmd)) != NULL) { - intptr_t ret = mingw_spawn_interpreter(mode, prog, argv, envp); + intptr_t ret = mingw_spawn_interpreter(mode, prog, argv, envp, 0); free(prog); return ret; } @@ -401,7 +403,7 @@ mingw_execvp(const char *cmd, char *const *argv) int mingw_execve(const char *cmd, char *const *argv, char *const *envp) { - int ret = (int)mingw_spawn_interpreter(P_WAIT, cmd, argv, envp); + int ret = (int)mingw_spawn_interpreter(P_WAIT, cmd, argv, envp, 0); if (ret != -1) exit(ret); return ret; -- cgit v1.2.3-55-g6feb