diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2013-04-07 18:16:58 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2013-04-07 18:16:58 +0200 |
commit | 3beab83e4f7f4213c185737e95dc4895f0059dd6 (patch) | |
tree | 89293330f61c17e734d5367954409a37261e95ca | |
parent | d35cbad0efaa57bf7c5280e62825966f7757906a (diff) | |
download | busybox-w32-3beab83e4f7f4213c185737e95dc4895f0059dd6.tar.gz busybox-w32-3beab83e4f7f4213c185737e95dc4895f0059dd6.tar.bz2 busybox-w32-3beab83e4f7f4213c185737e95dc4895f0059dd6.zip |
hush: fix for "while false && true; do echo BUG; break; done". closes 6170
function old new delta
run_list 959 941 -18
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | shell/hush.c | 19 | ||||
-rw-r--r-- | shell/hush_test/hush-misc/while4.right | 1 | ||||
-rwxr-xr-x | shell/hush_test/hush-misc/while4.tests | 6 |
3 files changed, 16 insertions, 10 deletions
diff --git a/shell/hush.c b/shell/hush.c index b23325725..1d421dc38 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -7354,7 +7354,7 @@ static int run_list(struct pipe *pi) | |||
7354 | * and we should not execute CMD */ | 7354 | * and we should not execute CMD */ |
7355 | debug_printf_exec("skipped cmd because of || or &&\n"); | 7355 | debug_printf_exec("skipped cmd because of || or &&\n"); |
7356 | last_followup = pi->followup; | 7356 | last_followup = pi->followup; |
7357 | continue; | 7357 | goto dont_check_jobs_but_continue; |
7358 | } | 7358 | } |
7359 | } | 7359 | } |
7360 | last_followup = pi->followup; | 7360 | last_followup = pi->followup; |
@@ -7493,8 +7493,10 @@ static int run_list(struct pipe *pi) | |||
7493 | G.flag_break_continue = 0; | 7493 | G.flag_break_continue = 0; |
7494 | /* else: e.g. "continue 2" should *break* once, *then* continue */ | 7494 | /* else: e.g. "continue 2" should *break* once, *then* continue */ |
7495 | } /* else: "while... do... { we are here (innermost list is not a loop!) };...done" */ | 7495 | } /* else: "while... do... { we are here (innermost list is not a loop!) };...done" */ |
7496 | if (G.depth_break_continue != 0 || fbc == BC_BREAK) | 7496 | if (G.depth_break_continue != 0 || fbc == BC_BREAK) { |
7497 | goto check_jobs_and_break; | 7497 | checkjobs(NULL); |
7498 | break; | ||
7499 | } | ||
7498 | /* "continue": simulate end of loop */ | 7500 | /* "continue": simulate end of loop */ |
7499 | rword = RES_DONE; | 7501 | rword = RES_DONE; |
7500 | continue; | 7502 | continue; |
@@ -7502,7 +7504,6 @@ static int run_list(struct pipe *pi) | |||
7502 | #endif | 7504 | #endif |
7503 | #if ENABLE_HUSH_FUNCTIONS | 7505 | #if ENABLE_HUSH_FUNCTIONS |
7504 | if (G.flag_return_in_progress == 1) { | 7506 | if (G.flag_return_in_progress == 1) { |
7505 | /* same as "goto check_jobs_and_break" */ | ||
7506 | checkjobs(NULL); | 7507 | checkjobs(NULL); |
7507 | break; | 7508 | break; |
7508 | } | 7509 | } |
@@ -7544,6 +7545,9 @@ static int run_list(struct pipe *pi) | |||
7544 | if (rword == RES_IF || rword == RES_ELIF) | 7545 | if (rword == RES_IF || rword == RES_ELIF) |
7545 | cond_code = rcode; | 7546 | cond_code = rcode; |
7546 | #endif | 7547 | #endif |
7548 | check_jobs_and_continue: | ||
7549 | checkjobs(NULL); | ||
7550 | dont_check_jobs_but_continue: ; | ||
7547 | #if ENABLE_HUSH_LOOPS | 7551 | #if ENABLE_HUSH_LOOPS |
7548 | /* Beware of "while false; true; do ..."! */ | 7552 | /* Beware of "while false; true; do ..."! */ |
7549 | if (pi->next | 7553 | if (pi->next |
@@ -7555,22 +7559,17 @@ static int run_list(struct pipe *pi) | |||
7555 | /* "while false; do...done" - exitcode 0 */ | 7559 | /* "while false; do...done" - exitcode 0 */ |
7556 | G.last_exitcode = rcode = EXIT_SUCCESS; | 7560 | G.last_exitcode = rcode = EXIT_SUCCESS; |
7557 | debug_printf_exec(": while expr is false: breaking (exitcode:EXIT_SUCCESS)\n"); | 7561 | debug_printf_exec(": while expr is false: breaking (exitcode:EXIT_SUCCESS)\n"); |
7558 | goto check_jobs_and_break; | 7562 | break; |
7559 | } | 7563 | } |
7560 | } | 7564 | } |
7561 | if (rword == RES_UNTIL) { | 7565 | if (rword == RES_UNTIL) { |
7562 | if (!rcode) { | 7566 | if (!rcode) { |
7563 | debug_printf_exec(": until expr is true: breaking\n"); | 7567 | debug_printf_exec(": until expr is true: breaking\n"); |
7564 | check_jobs_and_break: | ||
7565 | checkjobs(NULL); | ||
7566 | break; | 7568 | break; |
7567 | } | 7569 | } |
7568 | } | 7570 | } |
7569 | } | 7571 | } |
7570 | #endif | 7572 | #endif |
7571 | |||
7572 | check_jobs_and_continue: | ||
7573 | checkjobs(NULL); | ||
7574 | } /* for (pi) */ | 7573 | } /* for (pi) */ |
7575 | 7574 | ||
7576 | #if ENABLE_HUSH_JOB | 7575 | #if ENABLE_HUSH_JOB |
diff --git a/shell/hush_test/hush-misc/while4.right b/shell/hush_test/hush-misc/while4.right new file mode 100644 index 000000000..7b24a35ff --- /dev/null +++ b/shell/hush_test/hush-misc/while4.right | |||
@@ -0,0 +1 @@ | |||
Ok:0 | |||
diff --git a/shell/hush_test/hush-misc/while4.tests b/shell/hush_test/hush-misc/while4.tests new file mode 100755 index 000000000..ba80e603a --- /dev/null +++ b/shell/hush_test/hush-misc/while4.tests | |||
@@ -0,0 +1,6 @@ | |||
1 | false | ||
2 | while false && echo Not reached; do | ||
3 | echo BUG | ||
4 | break | ||
5 | done | ||
6 | echo Ok:$? | ||