diff options
author | Denys Vlasenko | 2018-04-05 15:15:53 +0200 |
---|---|---|
committer | Denys Vlasenko | 2018-04-05 15:15:53 +0200 |
commit | 21b7f1b6b67f191ca187910a5fd4cd2cb1eb5353 (patch) | |
tree | 3e9c5d63d0dd410b5fbd0eaf82cf051c105189a8 | |
parent | 41d8f1081378ec79586d59e7d2a31380b6f95577 (diff) | |
download | busybox-21b7f1b6b67f191ca187910a5fd4cd2cb1eb5353.zip busybox-21b7f1b6b67f191ca187910a5fd4cd2cb1eb5353.tar.gz |
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 4370236..577faf4 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -608,7 +608,7 @@ typedef enum redir_type { struct command { pid_t pid; /* 0 if exited */ - int assignment_cnt; /* how many argv[i] are assignments? */ + unsigned assignment_cnt; /* how many argv[i] are assignments? */ #if ENABLE_HUSH_LINENO_VAR unsigned lineno; #endif @@ -8317,25 +8317,26 @@ static NOINLINE int run_pipe(struct pipe *pi) * Ensure redirects take effect (that is, create files). * Try "a=t >file" */ - only_assignments: + unsigned i; G.expand_exitcode = 0; - + only_assignments: rcode = setup_redirects(command, &squirrel); restore_redirects(squirrel); + /* Set shell variables */ if (G_x_mode) bb_putchar_stderr('+'); - while (*argv) { - char *p = expand_string_to_string(*argv, /*unbackslash:*/ 1); + i = 0; + while (i < command->assignment_cnt) { + char *p = expand_string_to_string(argv[i], /*unbackslash:*/ 1); if (G_x_mode) fprintf(stderr, " %s", p); - debug_printf_exec("set shell var:'%s'->'%s'\n", - *argv, p); + debug_printf_env("set shell var:'%s'->'%s'\n", *argv, p); if (set_local_var(p, /*flag:*/ 0)) { /* assignment to readonly var / putenv error? */ rcode = 1; } - argv++; + i++; } if (G_x_mode) bb_putchar_stderr('\n'); @@ -8365,6 +8366,8 @@ static NOINLINE int run_pipe(struct pipe *pi) /* If someone gives us an empty string: `cmd with empty output` */ if (!argv_expanded[0]) { free(argv_expanded); + /* `false` still has to set exitcode 1 */ + G.expand_exitcode = G.last_exitcode; goto only_assignments; } @@ -10021,6 +10024,7 @@ static int helper_export_local(char **argv, unsigned flags) /* (Un)exporting/making local NAME=VALUE */ name = xstrdup(name); } + debug_printf_env("%s: set_local_var('%s')\n", __func__, name); if (set_local_var(name, flags)) return EXIT_FAILURE; } 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 0000000..670f560 --- /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 0000000..cfbd1a5 --- /dev/null +++ b/shell/hush_test/hush-psubst/falsetick2.tests @@ -0,0 +1,3 @@ +v=v +v=`exit 2` `false` +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 0000000..810cc23 --- /dev/null +++ b/shell/hush_test/hush-redir/redir_backquote1.right @@ -0,0 +1,11 @@ +hush: can't open '/cant/be/created': No such file or directory +First +One:1 v1:[] +hush: can't open '/cant/be/created': No such file or directory +Second +One:1 v2:[] +Third +Zero:0 v3:[] +Fourth +Zero:0 v4:[] +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 0000000..41bb491 --- /dev/null +++ b/shell/hush_test/hush-redir/redir_backquote1.tests @@ -0,0 +1,19 @@ +v=v +v=`echo First >&2` `` >/cant/be/created +echo One:$? v1:"[$v]" + +v=v +v=`echo Second >&2` `true` >/cant/be/created +echo One:$? v2:"[$v]" + +v=v +v=`echo Third >&2` `true` 2>/dev/null +echo Zero:$? v3:"[$v]" + +v=v +v=`echo Fourth >&2` `false` 2>/dev/null +echo Zero:$? v4:"[$v]" + +v=v +v=`echo $?` `false` 2>/dev/null +echo Zero:$? v5:"[$v]" |