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>
master
Denys Vlasenko 2024-02-10 18:51:39 +03:00
parent a97a2f1280
commit 2639f3bc72
1 changed files with 34 additions and 28 deletions

View File

@ -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" */
{