aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2008-06-17 12:09:21 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2008-06-17 12:09:21 +0000
commit6eaf8deddd3c2cd747b09fb038f9e56f18250714 (patch)
tree44cd58a2415de3951bd5d694a78139633f605fcf
parentb6926109b70cd6989384ea6ac1dc9dd9f842efc4 (diff)
downloadbusybox-w32-6eaf8deddd3c2cd747b09fb038f9e56f18250714.tar.gz
busybox-w32-6eaf8deddd3c2cd747b09fb038f9e56f18250714.tar.bz2
busybox-w32-6eaf8deddd3c2cd747b09fb038f9e56f18250714.zip
hush: fix "for a in; do echo 'I should never run'; done" bug
-rw-r--r--shell/hush.c18
-rw-r--r--shell/hush_test/hush-misc/empty_for.right (renamed from shell/hush_test/hush-bugs/empty_for.right)0
-rwxr-xr-xshell/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 ae12ebec4..45448c5f3 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -2004,7 +2004,7 @@ static int run_list(struct pipe *pi)
2004 || (rpipe->res_word == RES_FOR && rpipe->next->res_word != RES_IN) 2004 || (rpipe->res_word == RES_FOR && rpipe->next->res_word != RES_IN)
2005 ) { 2005 ) {
2006 /* TODO: what is tested in the first condition? */ 2006 /* TODO: what is tested in the first condition? */
2007 syntax("malformed for"); /* 2nd condition: not followed by IN */ 2007 syntax("malformed for"); /* 2nd condition: FOR not followed by IN */
2008 debug_printf_exec("run_list lvl %d return 1\n", run_list_level); 2008 debug_printf_exec("run_list lvl %d return 1\n", run_list_level);
2009 return 1; 2009 return 1;
2010 } 2010 }
@@ -2898,7 +2898,8 @@ static int done_word(o_string *word, struct p_context *ctx)
2898 ctx->pending_redirect = NULL; 2898 ctx->pending_redirect = NULL;
2899 } 2899 }
2900#if ENABLE_HUSH_LOOPS 2900#if ENABLE_HUSH_LOOPS
2901 if (ctx->res_w == RES_FOR) { /* comment? */ 2901 /* comment? is it forcing "for" to have just one word (variable name)? */
2902 if (ctx->res_w == RES_FOR) {
2902//TESTING 2903//TESTING
2903//looks like (word->length == 0 && !word->nonnull) is true here, always 2904//looks like (word->length == 0 && !word->nonnull) is true here, always
2904//(due to o_reset). done_word would return at once. Why then? 2905//(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)
2910 return 0; 2911 return 0;
2911} 2912}
2912 2913
2913/* The only possible error here is out of memory, in which case 2914/* Command (member of a pipe) is complete. The only possible error here
2914 * xmalloc exits. */ 2915 * is out of memory, in which case xmalloc exits. */
2915static int done_command(struct p_context *ctx) 2916static int done_command(struct p_context *ctx)
2916{ 2917{
2917 /* The child is really already in the pipe structure, so 2918 /* The child is really already in the pipe structure, so
@@ -2949,7 +2950,6 @@ static int done_command(struct p_context *ctx)
2949 2950
2950static void done_pipe(struct p_context *ctx, pipe_style type) 2951static void done_pipe(struct p_context *ctx, pipe_style type)
2951{ 2952{
2952 struct pipe *new_p;
2953 int not_null; 2953 int not_null;
2954 2954
2955 debug_printf_parse("done_pipe entered, followup %d\n", type); 2955 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)
2960 ctx->ctx_inverted = 0; 2960 ctx->ctx_inverted = 0;
2961 /* Without this check, even just <enter> on command line generates 2961 /* Without this check, even just <enter> on command line generates
2962 * tree of three NOPs (!). Which is harmless but annoying. 2962 * tree of three NOPs (!). Which is harmless but annoying.
2963 * IOW: it is safe to do it unconditionally. */ 2963 * IOW: it is safe to do it unconditionally.
2964 if (not_null) { 2964 * RES_IN case is for "for a in; do ..." (empty IN set)
2965 new_p = new_pipe(); 2965 * to work. */
2966 if (not_null || ctx->pipe->res_word == RES_IN) {
2967 struct pipe *new_p = new_pipe();
2966 ctx->pipe->next = new_p; 2968 ctx->pipe->next = new_p;
2967 ctx->pipe = new_p; 2969 ctx->pipe = new_p;
2968 ctx->child = NULL; /* needed! */ 2970 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 290d39b7e..290d39b7e 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 0cb52e849..0cb52e849 100755
--- a/shell/hush_test/hush-bugs/empty_for.tests
+++ b/shell/hush_test/hush-misc/empty_for.tests