diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2018-04-05 15:15:53 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2018-04-05 15:15:53 +0200 |
commit | 21b7f1b6b67f191ca187910a5fd4cd2cb1eb5353 (patch) | |
tree | 3e9c5d63d0dd410b5fbd0eaf82cf051c105189a8 /shell/hush.c | |
parent | 41d8f1081378ec79586d59e7d2a31380b6f95577 (diff) | |
download | busybox-w32-21b7f1b6b67f191ca187910a5fd4cd2cb1eb5353.tar.gz busybox-w32-21b7f1b6b67f191ca187910a5fd4cd2cb1eb5353.tar.bz2 busybox-w32-21b7f1b6b67f191ca187910a5fd4cd2cb1eb5353.zip |
hush: fix a few more corner cases with empty-expanding `cmds`
See added testcases
function old new delta
run_pipe 1723 1784 +61
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'shell/hush.c')
-rw-r--r-- | shell/hush.c | 20 |
1 files changed, 12 insertions, 8 deletions
diff --git a/shell/hush.c b/shell/hush.c index 43702360a..577faf466 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -608,7 +608,7 @@ typedef enum redir_type { | |||
608 | 608 | ||
609 | struct command { | 609 | struct command { |
610 | pid_t pid; /* 0 if exited */ | 610 | pid_t pid; /* 0 if exited */ |
611 | int assignment_cnt; /* how many argv[i] are assignments? */ | 611 | unsigned assignment_cnt; /* how many argv[i] are assignments? */ |
612 | #if ENABLE_HUSH_LINENO_VAR | 612 | #if ENABLE_HUSH_LINENO_VAR |
613 | unsigned lineno; | 613 | unsigned lineno; |
614 | #endif | 614 | #endif |
@@ -8317,25 +8317,26 @@ static NOINLINE int run_pipe(struct pipe *pi) | |||
8317 | * Ensure redirects take effect (that is, create files). | 8317 | * Ensure redirects take effect (that is, create files). |
8318 | * Try "a=t >file" | 8318 | * Try "a=t >file" |
8319 | */ | 8319 | */ |
8320 | only_assignments: | 8320 | unsigned i; |
8321 | G.expand_exitcode = 0; | 8321 | G.expand_exitcode = 0; |
8322 | 8322 | only_assignments: | |
8323 | rcode = setup_redirects(command, &squirrel); | 8323 | rcode = setup_redirects(command, &squirrel); |
8324 | restore_redirects(squirrel); | 8324 | restore_redirects(squirrel); |
8325 | |||
8325 | /* Set shell variables */ | 8326 | /* Set shell variables */ |
8326 | if (G_x_mode) | 8327 | if (G_x_mode) |
8327 | bb_putchar_stderr('+'); | 8328 | bb_putchar_stderr('+'); |
8328 | while (*argv) { | 8329 | i = 0; |
8329 | char *p = expand_string_to_string(*argv, /*unbackslash:*/ 1); | 8330 | while (i < command->assignment_cnt) { |
8331 | char *p = expand_string_to_string(argv[i], /*unbackslash:*/ 1); | ||
8330 | if (G_x_mode) | 8332 | if (G_x_mode) |
8331 | fprintf(stderr, " %s", p); | 8333 | fprintf(stderr, " %s", p); |
8332 | debug_printf_exec("set shell var:'%s'->'%s'\n", | 8334 | debug_printf_env("set shell var:'%s'->'%s'\n", *argv, p); |
8333 | *argv, p); | ||
8334 | if (set_local_var(p, /*flag:*/ 0)) { | 8335 | if (set_local_var(p, /*flag:*/ 0)) { |
8335 | /* assignment to readonly var / putenv error? */ | 8336 | /* assignment to readonly var / putenv error? */ |
8336 | rcode = 1; | 8337 | rcode = 1; |
8337 | } | 8338 | } |
8338 | argv++; | 8339 | i++; |
8339 | } | 8340 | } |
8340 | if (G_x_mode) | 8341 | if (G_x_mode) |
8341 | bb_putchar_stderr('\n'); | 8342 | bb_putchar_stderr('\n'); |
@@ -8365,6 +8366,8 @@ static NOINLINE int run_pipe(struct pipe *pi) | |||
8365 | /* If someone gives us an empty string: `cmd with empty output` */ | 8366 | /* If someone gives us an empty string: `cmd with empty output` */ |
8366 | if (!argv_expanded[0]) { | 8367 | if (!argv_expanded[0]) { |
8367 | free(argv_expanded); | 8368 | free(argv_expanded); |
8369 | /* `false` still has to set exitcode 1 */ | ||
8370 | G.expand_exitcode = G.last_exitcode; | ||
8368 | goto only_assignments; | 8371 | goto only_assignments; |
8369 | } | 8372 | } |
8370 | 8373 | ||
@@ -10021,6 +10024,7 @@ static int helper_export_local(char **argv, unsigned flags) | |||
10021 | /* (Un)exporting/making local NAME=VALUE */ | 10024 | /* (Un)exporting/making local NAME=VALUE */ |
10022 | name = xstrdup(name); | 10025 | name = xstrdup(name); |
10023 | } | 10026 | } |
10027 | debug_printf_env("%s: set_local_var('%s')\n", __func__, name); | ||
10024 | if (set_local_var(name, flags)) | 10028 | if (set_local_var(name, flags)) |
10025 | return EXIT_FAILURE; | 10029 | return EXIT_FAILURE; |
10026 | } while (*++argv); | 10030 | } while (*++argv); |