diff options
author | Denys Vlasenko | 2024-02-10 18:51:39 +0300 |
---|---|---|
committer | Denys Vlasenko | 2024-02-25 15:42:16 +0100 |
commit | 2639f3bc72ac2f03af7ccc825429ccb2fce99a16 (patch) | |
tree | 04f98e534a0b1366f91331979cace5af986ef637 /shell | |
parent | a97a2f12804668435e05cf98ae43e3a81e3da041 (diff) | |
download | busybox-2639f3bc72ac2f03af7ccc825429ccb2fce99a16.zip busybox-2639f3bc72ac2f03af7ccc825429ccb2fce99a16.tar.gz |
hush: set G.ifs sooner (prevents segfault)
function old new delta
set_G_ifs - 151 +151
run_list 1024 1031 +7
run_pipe 1567 1445 -122
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 1/1 up/down: 158/-122) Total: 36 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'shell')
-rw-r--r-- | shell/hush.c | 62 |
1 files changed, 34 insertions, 28 deletions
diff --git a/shell/hush.c b/shell/hush.c index ca01e2b..0c91008 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -9250,6 +9250,37 @@ static int checkjobs_and_fg_shell(struct pipe *fg_pipe) * backgrounded: cmd & { list } & * subshell: ( list ) [&] */ +static void set_G_ifs(void) +{ + /* Testcase: set -- q w e; (IFS='' echo "$*"; IFS=''; echo "$*"); echo "$*" + * Result should be 3 lines: q w e, qwe, q w e + */ + if (G.ifs_whitespace != G.ifs) + free(G.ifs_whitespace); + G.ifs = get_local_var_value("IFS"); + if (G.ifs) { + char *p; + G.ifs_whitespace = (char*)G.ifs; + p = skip_whitespace(G.ifs); + if (*p) { + /* Not all $IFS is whitespace */ + char *d; + int len = p - G.ifs; + p = skip_non_whitespace(p); + G.ifs_whitespace = xmalloc(len + strlen(p) + 1); /* can overestimate */ + d = mempcpy(G.ifs_whitespace, G.ifs, len); + while (*p) { + if (isspace(*p)) + *d++ = *p; + p++; + } + *d = '\0'; + } + } else { + G.ifs = defifs; + G.ifs_whitespace = (char*)G.ifs; + } +} #if !ENABLE_HUSH_MODE_X #define redirect_and_varexp_helper(command, sqp, argv_expanded) \ redirect_and_varexp_helper(command, sqp) @@ -9286,34 +9317,7 @@ static NOINLINE int run_pipe(struct pipe *pi) debug_printf_exec("run_pipe start: members:%d\n", pi->num_cmds); debug_enter(); - /* Testcase: set -- q w e; (IFS='' echo "$*"; IFS=''; echo "$*"); echo "$*" - * Result should be 3 lines: q w e, qwe, q w e - */ - if (G.ifs_whitespace != G.ifs) - free(G.ifs_whitespace); - G.ifs = get_local_var_value("IFS"); - if (G.ifs) { - char *p; - G.ifs_whitespace = (char*)G.ifs; - p = skip_whitespace(G.ifs); - if (*p) { - /* Not all $IFS is whitespace */ - char *d; - int len = p - G.ifs; - p = skip_non_whitespace(p); - G.ifs_whitespace = xmalloc(len + strlen(p) + 1); /* can overestimate */ - d = mempcpy(G.ifs_whitespace, G.ifs, len); - while (*p) { - if (isspace(*p)) - *d++ = *p; - p++; - } - *d = '\0'; - } - } else { - G.ifs = defifs; - G.ifs_whitespace = (char*)G.ifs; - } + set_G_ifs(); IF_HUSH_JOB(pi->pgrp = -1;) pi->stopped_cmds = 0; @@ -9758,6 +9762,8 @@ static int run_list(struct pipe *pi) debug_printf_exec("run_list lvl %d start\n", G.run_list_level); debug_enter(); + set_G_ifs(); + #if ENABLE_HUSH_LOOPS /* Check syntax for "for" */ { |