diff options
author | Denis Vlasenko | 2008-06-17 12:09:21 +0000 |
---|---|---|
committer | Denis Vlasenko | 2008-06-17 12:09:21 +0000 |
commit | 6eaf8deddd3c2cd747b09fb038f9e56f18250714 (patch) | |
tree | 44cd58a2415de3951bd5d694a78139633f605fcf | |
parent | b6926109b70cd6989384ea6ac1dc9dd9f842efc4 (diff) | |
download | busybox-6eaf8deddd3c2cd747b09fb038f9e56f18250714.zip busybox-6eaf8deddd3c2cd747b09fb038f9e56f18250714.tar.gz |
hush: fix "for a in; do echo 'I should never run'; done" bug
-rw-r--r-- | shell/hush.c | 18 | ||||
-rw-r--r-- | shell/hush_test/hush-misc/empty_for.right (renamed from shell/hush_test/hush-bugs/empty_for.right) | 0 | ||||
-rwxr-xr-x | shell/hush_test/hush-misc/empty_for.tests (renamed from shell/hush_test/hush-bugs/empty_for.tests) | 0 |
3 files changed, 10 insertions, 8 deletions
diff --git a/shell/hush.c b/shell/hush.c index ae12ebe..45448c5 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -2004,7 +2004,7 @@ static int run_list(struct pipe *pi) || (rpipe->res_word == RES_FOR && rpipe->next->res_word != RES_IN) ) { /* TODO: what is tested in the first condition? */ - syntax("malformed for"); /* 2nd condition: not followed by IN */ + syntax("malformed for"); /* 2nd condition: FOR not followed by IN */ debug_printf_exec("run_list lvl %d return 1\n", run_list_level); return 1; } @@ -2898,7 +2898,8 @@ static int done_word(o_string *word, struct p_context *ctx) ctx->pending_redirect = NULL; } #if ENABLE_HUSH_LOOPS - if (ctx->res_w == RES_FOR) { /* comment? */ + /* comment? is it forcing "for" to have just one word (variable name)? */ + if (ctx->res_w == RES_FOR) { //TESTING //looks like (word->length == 0 && !word->nonnull) is true here, always //(due to o_reset). done_word would return at once. Why then? @@ -2910,8 +2911,8 @@ static int done_word(o_string *word, struct p_context *ctx) return 0; } -/* The only possible error here is out of memory, in which case - * xmalloc exits. */ +/* Command (member of a pipe) is complete. The only possible error here + * is out of memory, in which case xmalloc exits. */ static int done_command(struct p_context *ctx) { /* The child is really already in the pipe structure, so @@ -2949,7 +2950,6 @@ static int done_command(struct p_context *ctx) static void done_pipe(struct p_context *ctx, pipe_style type) { - struct pipe *new_p; int not_null; debug_printf_parse("done_pipe entered, followup %d\n", type); @@ -2960,9 +2960,11 @@ static void done_pipe(struct p_context *ctx, pipe_style type) ctx->ctx_inverted = 0; /* Without this check, even just <enter> on command line generates * tree of three NOPs (!). Which is harmless but annoying. - * IOW: it is safe to do it unconditionally. */ - if (not_null) { - new_p = new_pipe(); + * IOW: it is safe to do it unconditionally. + * RES_IN case is for "for a in; do ..." (empty IN set) + * to work. */ + if (not_null || ctx->pipe->res_word == RES_IN) { + struct pipe *new_p = new_pipe(); ctx->pipe->next = new_p; ctx->pipe = new_p; ctx->child = NULL; /* needed! */ diff --git a/shell/hush_test/hush-bugs/empty_for.right b/shell/hush_test/hush-misc/empty_for.right index 290d39b..290d39b 100644 --- a/shell/hush_test/hush-bugs/empty_for.right +++ b/shell/hush_test/hush-misc/empty_for.right diff --git a/shell/hush_test/hush-bugs/empty_for.tests b/shell/hush_test/hush-misc/empty_for.tests index 0cb52e8..0cb52e8 100755 --- a/shell/hush_test/hush-bugs/empty_for.tests +++ b/shell/hush_test/hush-misc/empty_for.tests |