diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2024-02-10 18:51:39 +0300 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2024-02-25 15:42:16 +0100 |
commit | 2639f3bc72ac2f03af7ccc825429ccb2fce99a16 (patch) | |
tree | 04f98e534a0b1366f91331979cace5af986ef637 | |
parent | a97a2f12804668435e05cf98ae43e3a81e3da041 (diff) | |
download | busybox-w32-2639f3bc72ac2f03af7ccc825429ccb2fce99a16.tar.gz busybox-w32-2639f3bc72ac2f03af7ccc825429ccb2fce99a16.tar.bz2 busybox-w32-2639f3bc72ac2f03af7ccc825429ccb2fce99a16.zip |
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.c | 62 |
1 files changed, 34 insertions, 28 deletions
diff --git a/shell/hush.c b/shell/hush.c index ca01e2b5b..0c91008b9 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -9250,6 +9250,37 @@ static int checkjobs_and_fg_shell(struct pipe *fg_pipe) | |||
9250 | * backgrounded: cmd & { list } & | 9250 | * backgrounded: cmd & { list } & |
9251 | * subshell: ( list ) [&] | 9251 | * subshell: ( list ) [&] |
9252 | */ | 9252 | */ |
9253 | static void set_G_ifs(void) | ||
9254 | { | ||
9255 | /* Testcase: set -- q w e; (IFS='' echo "$*"; IFS=''; echo "$*"); echo "$*" | ||
9256 | * Result should be 3 lines: q w e, qwe, q w e | ||
9257 | */ | ||
9258 | if (G.ifs_whitespace != G.ifs) | ||
9259 | free(G.ifs_whitespace); | ||
9260 | G.ifs = get_local_var_value("IFS"); | ||
9261 | if (G.ifs) { | ||
9262 | char *p; | ||
9263 | G.ifs_whitespace = (char*)G.ifs; | ||
9264 | p = skip_whitespace(G.ifs); | ||
9265 | if (*p) { | ||
9266 | /* Not all $IFS is whitespace */ | ||
9267 | char *d; | ||
9268 | int len = p - G.ifs; | ||
9269 | p = skip_non_whitespace(p); | ||
9270 | G.ifs_whitespace = xmalloc(len + strlen(p) + 1); /* can overestimate */ | ||
9271 | d = mempcpy(G.ifs_whitespace, G.ifs, len); | ||
9272 | while (*p) { | ||
9273 | if (isspace(*p)) | ||
9274 | *d++ = *p; | ||
9275 | p++; | ||
9276 | } | ||
9277 | *d = '\0'; | ||
9278 | } | ||
9279 | } else { | ||
9280 | G.ifs = defifs; | ||
9281 | G.ifs_whitespace = (char*)G.ifs; | ||
9282 | } | ||
9283 | } | ||
9253 | #if !ENABLE_HUSH_MODE_X | 9284 | #if !ENABLE_HUSH_MODE_X |
9254 | #define redirect_and_varexp_helper(command, sqp, argv_expanded) \ | 9285 | #define redirect_and_varexp_helper(command, sqp, argv_expanded) \ |
9255 | redirect_and_varexp_helper(command, sqp) | 9286 | redirect_and_varexp_helper(command, sqp) |
@@ -9286,34 +9317,7 @@ static NOINLINE int run_pipe(struct pipe *pi) | |||
9286 | debug_printf_exec("run_pipe start: members:%d\n", pi->num_cmds); | 9317 | debug_printf_exec("run_pipe start: members:%d\n", pi->num_cmds); |
9287 | debug_enter(); | 9318 | debug_enter(); |
9288 | 9319 | ||
9289 | /* Testcase: set -- q w e; (IFS='' echo "$*"; IFS=''; echo "$*"); echo "$*" | 9320 | set_G_ifs(); |
9290 | * Result should be 3 lines: q w e, qwe, q w e | ||
9291 | */ | ||
9292 | if (G.ifs_whitespace != G.ifs) | ||
9293 | free(G.ifs_whitespace); | ||
9294 | G.ifs = get_local_var_value("IFS"); | ||
9295 | if (G.ifs) { | ||
9296 | char *p; | ||
9297 | G.ifs_whitespace = (char*)G.ifs; | ||
9298 | p = skip_whitespace(G.ifs); | ||
9299 | if (*p) { | ||
9300 | /* Not all $IFS is whitespace */ | ||
9301 | char *d; | ||
9302 | int len = p - G.ifs; | ||
9303 | p = skip_non_whitespace(p); | ||
9304 | G.ifs_whitespace = xmalloc(len + strlen(p) + 1); /* can overestimate */ | ||
9305 | d = mempcpy(G.ifs_whitespace, G.ifs, len); | ||
9306 | while (*p) { | ||
9307 | if (isspace(*p)) | ||
9308 | *d++ = *p; | ||
9309 | p++; | ||
9310 | } | ||
9311 | *d = '\0'; | ||
9312 | } | ||
9313 | } else { | ||
9314 | G.ifs = defifs; | ||
9315 | G.ifs_whitespace = (char*)G.ifs; | ||
9316 | } | ||
9317 | 9321 | ||
9318 | IF_HUSH_JOB(pi->pgrp = -1;) | 9322 | IF_HUSH_JOB(pi->pgrp = -1;) |
9319 | pi->stopped_cmds = 0; | 9323 | pi->stopped_cmds = 0; |
@@ -9758,6 +9762,8 @@ static int run_list(struct pipe *pi) | |||
9758 | debug_printf_exec("run_list lvl %d start\n", G.run_list_level); | 9762 | debug_printf_exec("run_list lvl %d start\n", G.run_list_level); |
9759 | debug_enter(); | 9763 | debug_enter(); |
9760 | 9764 | ||
9765 | set_G_ifs(); | ||
9766 | |||
9761 | #if ENABLE_HUSH_LOOPS | 9767 | #if ENABLE_HUSH_LOOPS |
9762 | /* Check syntax for "for" */ | 9768 | /* Check syntax for "for" */ |
9763 | { | 9769 | { |