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 | |
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')
-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]" | ||