aboutsummaryrefslogtreecommitdiff
path: root/shell
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2023-05-25 14:22:10 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2023-05-25 14:22:10 +0200
commit6824298ab4d3da40763af4d2d466a72745b8b593 (patch)
tree13382dd9610b5154e79ad971f17f1dc54f13ea1a /shell
parent3e83699ce23400d75c7ddaa7ebfdec015177caa7 (diff)
downloadbusybox-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.right4
-rwxr-xr-xshell/ash_test/ash-misc/elif1.tests6
-rw-r--r--shell/ash_test/ash-misc/elif2.right2
-rwxr-xr-xshell/ash_test/ash-misc/elif2.tests8
-rw-r--r--shell/hush.c24
-rw-r--r--shell/hush_test/hush-misc/elif1.right4
-rwxr-xr-xshell/hush_test/hush-misc/elif1.tests6
-rw-r--r--shell/hush_test/hush-misc/elif2.right2
-rwxr-xr-xshell/hush_test/hush-misc/elif2.tests8
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 @@
1ELIF1
2ELIF2
3ELIF THEN
4Ok: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 @@
1if false; then
2 :
3elif echo 'ELIF1'; echo 'ELIF2'; then
4 echo "ELIF THEN"
5fi
6echo "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 @@
1THEN
2Ok: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 @@
1if true; then
2 echo "THEN"
3elif echo "ELIF false"; false; then
4 echo "ELIF THEN"
5else
6 echo "ELSE"
7fi
8echo "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 @@
1ELIF1
2ELIF2
3ELIF THEN
4Ok: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 @@
1if false; then
2 :
3elif echo 'ELIF1'; echo 'ELIF2'; then
4 echo "ELIF THEN"
5fi
6echo "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 @@
1THEN
2Ok: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 @@
1if true; then
2 echo "THEN"
3elif echo "ELIF false"; false; then
4 echo "ELIF THEN"
5else
6 echo "ELSE"
7fi
8echo "Ok:$?"