From 6eaf8deddd3c2cd747b09fb038f9e56f18250714 Mon Sep 17 00:00:00 2001 From: Denis Vlasenko Date: Tue, 17 Jun 2008 12:09:21 +0000 Subject: hush: fix "for a in; do echo 'I should never run'; done" bug --- shell/hush.c | 18 ++++++++++-------- shell/hush_test/hush-bugs/empty_for.right | 1 - shell/hush_test/hush-bugs/empty_for.tests | 3 --- shell/hush_test/hush-misc/empty_for.right | 1 + shell/hush_test/hush-misc/empty_for.tests | 3 +++ 5 files changed, 14 insertions(+), 12 deletions(-) delete mode 100644 shell/hush_test/hush-bugs/empty_for.right delete mode 100755 shell/hush_test/hush-bugs/empty_for.tests create mode 100644 shell/hush_test/hush-misc/empty_for.right create mode 100755 shell/hush_test/hush-misc/empty_for.tests 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 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-bugs/empty_for.right deleted file mode 100644 index 290d39b..0000000 --- a/shell/hush_test/hush-bugs/empty_for.right +++ /dev/null @@ -1 +0,0 @@ -OK: 0 diff --git a/shell/hush_test/hush-bugs/empty_for.tests b/shell/hush_test/hush-bugs/empty_for.tests deleted file mode 100755 index 0cb52e8..0000000 --- a/shell/hush_test/hush-bugs/empty_for.tests +++ /dev/null @@ -1,3 +0,0 @@ -false -for a in; do echo "HELLO"; done -echo OK: $? diff --git a/shell/hush_test/hush-misc/empty_for.right b/shell/hush_test/hush-misc/empty_for.right new file mode 100644 index 0000000..290d39b --- /dev/null +++ b/shell/hush_test/hush-misc/empty_for.right @@ -0,0 +1 @@ +OK: 0 diff --git a/shell/hush_test/hush-misc/empty_for.tests b/shell/hush_test/hush-misc/empty_for.tests new file mode 100755 index 0000000..0cb52e8 --- /dev/null +++ b/shell/hush_test/hush-misc/empty_for.tests @@ -0,0 +1,3 @@ +false +for a in; do echo "HELLO"; done +echo OK: $? -- cgit v1.1