diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2023-05-25 14:22:10 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2023-05-25 14:22:10 +0200 |
commit | 6824298ab4d3da40763af4d2d466a72745b8b593 (patch) | |
tree | 13382dd9610b5154e79ad971f17f1dc54f13ea1a /shell | |
parent | 3e83699ce23400d75c7ddaa7ebfdec015177caa7 (diff) | |
download | busybox-w32-6824298ab4d3da40763af4d2d466a72745b8b593.tar.gz busybox-w32-6824298ab4d3da40763af4d2d466a72745b8b593.tar.bz2 busybox-w32-6824298ab4d3da40763af4d2d466a72745b8b593.zip |
hush: fix ELIF cmd1;cmd2 THEN ... not executing cmd2, closes 15571
function old new delta
run_list 1012 1024 +12
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'shell')
-rw-r--r-- | shell/ash_test/ash-misc/elif1.right | 4 | ||||
-rwxr-xr-x | shell/ash_test/ash-misc/elif1.tests | 6 | ||||
-rw-r--r-- | shell/ash_test/ash-misc/elif2.right | 2 | ||||
-rwxr-xr-x | shell/ash_test/ash-misc/elif2.tests | 8 | ||||
-rw-r--r-- | shell/hush.c | 24 | ||||
-rw-r--r-- | shell/hush_test/hush-misc/elif1.right | 4 | ||||
-rwxr-xr-x | shell/hush_test/hush-misc/elif1.tests | 6 | ||||
-rw-r--r-- | shell/hush_test/hush-misc/elif2.right | 2 | ||||
-rwxr-xr-x | shell/hush_test/hush-misc/elif2.tests | 8 |
9 files changed, 56 insertions, 8 deletions
diff --git a/shell/ash_test/ash-misc/elif1.right b/shell/ash_test/ash-misc/elif1.right new file mode 100644 index 000000000..36dc59fed --- /dev/null +++ b/shell/ash_test/ash-misc/elif1.right | |||
@@ -0,0 +1,4 @@ | |||
1 | ELIF1 | ||
2 | ELIF2 | ||
3 | ELIF THEN | ||
4 | Ok:0 | ||
diff --git a/shell/ash_test/ash-misc/elif1.tests b/shell/ash_test/ash-misc/elif1.tests new file mode 100755 index 000000000..77b8a25ea --- /dev/null +++ b/shell/ash_test/ash-misc/elif1.tests | |||
@@ -0,0 +1,6 @@ | |||
1 | if false; then | ||
2 | : | ||
3 | elif echo 'ELIF1'; echo 'ELIF2'; then | ||
4 | echo "ELIF THEN" | ||
5 | fi | ||
6 | echo "Ok:$?" | ||
diff --git a/shell/ash_test/ash-misc/elif2.right b/shell/ash_test/ash-misc/elif2.right new file mode 100644 index 000000000..8f2851f91 --- /dev/null +++ b/shell/ash_test/ash-misc/elif2.right | |||
@@ -0,0 +1,2 @@ | |||
1 | THEN | ||
2 | Ok:0 | ||
diff --git a/shell/ash_test/ash-misc/elif2.tests b/shell/ash_test/ash-misc/elif2.tests new file mode 100755 index 000000000..3e5876f05 --- /dev/null +++ b/shell/ash_test/ash-misc/elif2.tests | |||
@@ -0,0 +1,8 @@ | |||
1 | if true; then | ||
2 | echo "THEN" | ||
3 | elif echo "ELIF false"; false; then | ||
4 | echo "ELIF THEN" | ||
5 | else | ||
6 | echo "ELSE" | ||
7 | fi | ||
8 | echo "Ok:$?" | ||
diff --git a/shell/hush.c b/shell/hush.c index 810dafd35..1f7b58d4f 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -9758,7 +9758,7 @@ static int run_list(struct pipe *pi) | |||
9758 | smallint last_rword; /* ditto */ | 9758 | smallint last_rword; /* ditto */ |
9759 | #endif | 9759 | #endif |
9760 | 9760 | ||
9761 | debug_printf_exec("run_list start lvl %d\n", G.run_list_level); | 9761 | debug_printf_exec("run_list lvl %d start\n", G.run_list_level); |
9762 | debug_enter(); | 9762 | debug_enter(); |
9763 | 9763 | ||
9764 | #if ENABLE_HUSH_LOOPS | 9764 | #if ENABLE_HUSH_LOOPS |
@@ -9817,7 +9817,7 @@ static int run_list(struct pipe *pi) | |||
9817 | break; | 9817 | break; |
9818 | 9818 | ||
9819 | IF_HAS_KEYWORDS(rword = pi->res_word;) | 9819 | IF_HAS_KEYWORDS(rword = pi->res_word;) |
9820 | debug_printf_exec(": rword=%d cond_code=%d last_rword=%d\n", | 9820 | debug_printf_exec(": rword:%d cond_code:%d last_rword:%d\n", |
9821 | rword, cond_code, last_rword); | 9821 | rword, cond_code, last_rword); |
9822 | 9822 | ||
9823 | sv_errexit_depth = G.errexit_depth; | 9823 | sv_errexit_depth = G.errexit_depth; |
@@ -9851,23 +9851,29 @@ static int run_list(struct pipe *pi) | |||
9851 | } | 9851 | } |
9852 | } | 9852 | } |
9853 | last_followup = pi->followup; | 9853 | last_followup = pi->followup; |
9854 | IF_HAS_KEYWORDS(last_rword = rword;) | ||
9855 | #if ENABLE_HUSH_IF | 9854 | #if ENABLE_HUSH_IF |
9856 | if (cond_code) { | 9855 | if (cond_code != 0) { |
9857 | if (rword == RES_THEN) { | 9856 | if (rword == RES_THEN) { |
9858 | /* if false; then ... fi has exitcode 0! */ | 9857 | /* if false; then ... fi has exitcode 0! */ |
9859 | G.last_exitcode = rcode = EXIT_SUCCESS; | 9858 | G.last_exitcode = rcode = EXIT_SUCCESS; |
9860 | /* "if <false> THEN cmd": skip cmd */ | 9859 | /* "if <false> THEN cmd": skip cmd */ |
9860 | debug_printf_exec("skipped THEN cmd because IF condition was false\n"); | ||
9861 | last_rword = rword; | ||
9861 | continue; | 9862 | continue; |
9862 | } | 9863 | } |
9863 | } else { | 9864 | } else { |
9864 | if (rword == RES_ELSE || rword == RES_ELIF) { | 9865 | if (rword == RES_ELSE |
9866 | || (rword == RES_ELIF && last_rword != RES_ELIF) | ||
9867 | ) { | ||
9865 | /* "if <true> then ... ELSE/ELIF cmd": | 9868 | /* "if <true> then ... ELSE/ELIF cmd": |
9866 | * skip cmd and all following ones */ | 9869 | * skip cmd and all following ones */ |
9870 | debug_printf_exec("skipped ELSE/ELIF branch because IF condition was true\n"); | ||
9867 | break; | 9871 | break; |
9868 | } | 9872 | } |
9873 | //if (rword == RES_THEN): "if <true> THEN cmd", run cmd (fall through) | ||
9869 | } | 9874 | } |
9870 | #endif | 9875 | #endif |
9876 | IF_HAS_KEYWORDS(last_rword = rword;) | ||
9871 | #if ENABLE_HUSH_LOOPS | 9877 | #if ENABLE_HUSH_LOOPS |
9872 | if (rword == RES_FOR) { /* && pi->num_cmds - always == 1 */ | 9878 | if (rword == RES_FOR) { /* && pi->num_cmds - always == 1 */ |
9873 | if (!for_lcur) { | 9879 | if (!for_lcur) { |
@@ -9943,7 +9949,7 @@ static int run_list(struct pipe *pi) | |||
9943 | ); | 9949 | ); |
9944 | /* TODO: which FNM_xxx flags to use? */ | 9950 | /* TODO: which FNM_xxx flags to use? */ |
9945 | cond_code = (fnmatch(pattern, case_word, /*flags:*/ 0) != 0); | 9951 | cond_code = (fnmatch(pattern, case_word, /*flags:*/ 0) != 0); |
9946 | debug_printf_exec("fnmatch(pattern:'%s',str:'%s'):%d\n", | 9952 | debug_printf_exec("cond_code=fnmatch(pattern:'%s',str:'%s'):%d\n", |
9947 | pattern, case_word, cond_code); | 9953 | pattern, case_word, cond_code); |
9948 | free(pattern); | 9954 | free(pattern); |
9949 | if (cond_code == 0) { | 9955 | if (cond_code == 0) { |
@@ -10069,8 +10075,10 @@ static int run_list(struct pipe *pi) | |||
10069 | 10075 | ||
10070 | /* Analyze how result affects subsequent commands */ | 10076 | /* Analyze how result affects subsequent commands */ |
10071 | #if ENABLE_HUSH_IF | 10077 | #if ENABLE_HUSH_IF |
10072 | if (rword == RES_IF || rword == RES_ELIF) | 10078 | if (rword == RES_IF || rword == RES_ELIF) { |
10079 | debug_printf_exec("cond_code=rcode:%d\n", rcode); | ||
10073 | cond_code = rcode; | 10080 | cond_code = rcode; |
10081 | } | ||
10074 | #endif | 10082 | #endif |
10075 | check_jobs_and_continue: | 10083 | check_jobs_and_continue: |
10076 | checkjobs(NULL, 0 /*(no pid to wait for)*/); | 10084 | checkjobs(NULL, 0 /*(no pid to wait for)*/); |
@@ -10111,7 +10119,7 @@ static int run_list(struct pipe *pi) | |||
10111 | free(case_word); | 10119 | free(case_word); |
10112 | #endif | 10120 | #endif |
10113 | debug_leave(); | 10121 | debug_leave(); |
10114 | debug_printf_exec("run_list lvl %d return %d\n", G.run_list_level + 1, rcode); | 10122 | debug_printf_exec("run_list lvl %d return %d\n", G.run_list_level, rcode); |
10115 | return rcode; | 10123 | return rcode; |
10116 | } | 10124 | } |
10117 | 10125 | ||
diff --git a/shell/hush_test/hush-misc/elif1.right b/shell/hush_test/hush-misc/elif1.right new file mode 100644 index 000000000..36dc59fed --- /dev/null +++ b/shell/hush_test/hush-misc/elif1.right | |||
@@ -0,0 +1,4 @@ | |||
1 | ELIF1 | ||
2 | ELIF2 | ||
3 | ELIF THEN | ||
4 | Ok:0 | ||
diff --git a/shell/hush_test/hush-misc/elif1.tests b/shell/hush_test/hush-misc/elif1.tests new file mode 100755 index 000000000..77b8a25ea --- /dev/null +++ b/shell/hush_test/hush-misc/elif1.tests | |||
@@ -0,0 +1,6 @@ | |||
1 | if false; then | ||
2 | : | ||
3 | elif echo 'ELIF1'; echo 'ELIF2'; then | ||
4 | echo "ELIF THEN" | ||
5 | fi | ||
6 | echo "Ok:$?" | ||
diff --git a/shell/hush_test/hush-misc/elif2.right b/shell/hush_test/hush-misc/elif2.right new file mode 100644 index 000000000..8f2851f91 --- /dev/null +++ b/shell/hush_test/hush-misc/elif2.right | |||
@@ -0,0 +1,2 @@ | |||
1 | THEN | ||
2 | Ok:0 | ||
diff --git a/shell/hush_test/hush-misc/elif2.tests b/shell/hush_test/hush-misc/elif2.tests new file mode 100755 index 000000000..3e5876f05 --- /dev/null +++ b/shell/hush_test/hush-misc/elif2.tests | |||
@@ -0,0 +1,8 @@ | |||
1 | if true; then | ||
2 | echo "THEN" | ||
3 | elif echo "ELIF false"; false; then | ||
4 | echo "ELIF THEN" | ||
5 | else | ||
6 | echo "ELSE" | ||
7 | fi | ||
8 | echo "Ok:$?" | ||