summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko2024-02-10 18:51:39 +0300
committerDenys Vlasenko2024-02-25 15:42:16 +0100
commit2639f3bc72ac2f03af7ccc825429ccb2fce99a16 (patch)
tree04f98e534a0b1366f91331979cace5af986ef637
parenta97a2f12804668435e05cf98ae43e3a81e3da041 (diff)
downloadbusybox-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>
-rw-r--r--shell/hush.c62
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" */
{