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 | |
| 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>
| -rw-r--r-- | shell/hush.c | 20 | ||||
| -rw-r--r-- | shell/hush_test/hush-psubst/falsetick2.right | 1 | ||||
| -rwxr-xr-x | shell/hush_test/hush-psubst/falsetick2.tests | 3 | ||||
| -rw-r--r-- | shell/hush_test/hush-redir/redir_backquote1.right | 11 | ||||
| -rwxr-xr-x | shell/hush_test/hush-redir/redir_backquote1.tests | 19 |
5 files changed, 46 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); |
diff --git a/shell/hush_test/hush-psubst/falsetick2.right b/shell/hush_test/hush-psubst/falsetick2.right new file mode 100644 index 000000000..670f560f1 --- /dev/null +++ b/shell/hush_test/hush-psubst/falsetick2.right | |||
| @@ -0,0 +1 @@ | |||
| Two:2 v:[] | |||
diff --git a/shell/hush_test/hush-psubst/falsetick2.tests b/shell/hush_test/hush-psubst/falsetick2.tests new file mode 100755 index 000000000..cfbd1a5de --- /dev/null +++ b/shell/hush_test/hush-psubst/falsetick2.tests | |||
| @@ -0,0 +1,3 @@ | |||
| 1 | v=v | ||
| 2 | v=`exit 2` `false` | ||
| 3 | echo Two:$? v:"[$v]" | ||
diff --git a/shell/hush_test/hush-redir/redir_backquote1.right b/shell/hush_test/hush-redir/redir_backquote1.right new file mode 100644 index 000000000..810cc2314 --- /dev/null +++ b/shell/hush_test/hush-redir/redir_backquote1.right | |||
| @@ -0,0 +1,11 @@ | |||
| 1 | hush: can't open '/cant/be/created': No such file or directory | ||
| 2 | First | ||
| 3 | One:1 v1:[] | ||
| 4 | hush: can't open '/cant/be/created': No such file or directory | ||
| 5 | Second | ||
| 6 | One:1 v2:[] | ||
| 7 | Third | ||
| 8 | Zero:0 v3:[] | ||
| 9 | Fourth | ||
| 10 | Zero:0 v4:[] | ||
| 11 | Zero:0 v5:[1] | ||
diff --git a/shell/hush_test/hush-redir/redir_backquote1.tests b/shell/hush_test/hush-redir/redir_backquote1.tests new file mode 100755 index 000000000..41bb4913c --- /dev/null +++ b/shell/hush_test/hush-redir/redir_backquote1.tests | |||
| @@ -0,0 +1,19 @@ | |||
| 1 | v=v | ||
| 2 | v=`echo First >&2` `` >/cant/be/created | ||
| 3 | echo One:$? v1:"[$v]" | ||
| 4 | |||
| 5 | v=v | ||
| 6 | v=`echo Second >&2` `true` >/cant/be/created | ||
| 7 | echo One:$? v2:"[$v]" | ||
| 8 | |||
| 9 | v=v | ||
| 10 | v=`echo Third >&2` `true` 2>/dev/null | ||
| 11 | echo Zero:$? v3:"[$v]" | ||
| 12 | |||
| 13 | v=v | ||
| 14 | v=`echo Fourth >&2` `false` 2>/dev/null | ||
| 15 | echo Zero:$? v4:"[$v]" | ||
| 16 | |||
| 17 | v=v | ||
| 18 | v=`echo $?` `false` 2>/dev/null | ||
| 19 | echo Zero:$? v5:"[$v]" | ||
