From 6824298ab4d3da40763af4d2d466a72745b8b593 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 25 May 2023 14:22:10 +0200 Subject: 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 --- shell/ash_test/ash-misc/elif1.right | 4 ++++ shell/ash_test/ash-misc/elif1.tests | 6 ++++++ shell/ash_test/ash-misc/elif2.right | 2 ++ shell/ash_test/ash-misc/elif2.tests | 8 ++++++++ shell/hush.c | 24 ++++++++++++++++-------- shell/hush_test/hush-misc/elif1.right | 4 ++++ shell/hush_test/hush-misc/elif1.tests | 6 ++++++ shell/hush_test/hush-misc/elif2.right | 2 ++ shell/hush_test/hush-misc/elif2.tests | 8 ++++++++ 9 files changed, 56 insertions(+), 8 deletions(-) create mode 100644 shell/ash_test/ash-misc/elif1.right create mode 100755 shell/ash_test/ash-misc/elif1.tests create mode 100644 shell/ash_test/ash-misc/elif2.right create mode 100755 shell/ash_test/ash-misc/elif2.tests create mode 100644 shell/hush_test/hush-misc/elif1.right create mode 100755 shell/hush_test/hush-misc/elif1.tests create mode 100644 shell/hush_test/hush-misc/elif2.right create mode 100755 shell/hush_test/hush-misc/elif2.tests diff --git a/shell/ash_test/ash-misc/elif1.right b/shell/ash_test/ash-misc/elif1.right new file mode 100644 index 0000000..36dc59f --- /dev/null +++ b/shell/ash_test/ash-misc/elif1.right @@ -0,0 +1,4 @@ +ELIF1 +ELIF2 +ELIF THEN +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 0000000..77b8a25 --- /dev/null +++ b/shell/ash_test/ash-misc/elif1.tests @@ -0,0 +1,6 @@ +if false; then + : +elif echo 'ELIF1'; echo 'ELIF2'; then + echo "ELIF THEN" +fi +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 0000000..8f2851f --- /dev/null +++ b/shell/ash_test/ash-misc/elif2.right @@ -0,0 +1,2 @@ +THEN +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 0000000..3e5876f --- /dev/null +++ b/shell/ash_test/ash-misc/elif2.tests @@ -0,0 +1,8 @@ +if true; then + echo "THEN" +elif echo "ELIF false"; false; then + echo "ELIF THEN" +else + echo "ELSE" +fi +echo "Ok:$?" diff --git a/shell/hush.c b/shell/hush.c index 810dafd..1f7b58d 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -9758,7 +9758,7 @@ static int run_list(struct pipe *pi) smallint last_rword; /* ditto */ #endif - debug_printf_exec("run_list start lvl %d\n", G.run_list_level); + debug_printf_exec("run_list lvl %d start\n", G.run_list_level); debug_enter(); #if ENABLE_HUSH_LOOPS @@ -9817,7 +9817,7 @@ static int run_list(struct pipe *pi) break; IF_HAS_KEYWORDS(rword = pi->res_word;) - debug_printf_exec(": rword=%d cond_code=%d last_rword=%d\n", + debug_printf_exec(": rword:%d cond_code:%d last_rword:%d\n", rword, cond_code, last_rword); sv_errexit_depth = G.errexit_depth; @@ -9851,23 +9851,29 @@ static int run_list(struct pipe *pi) } } last_followup = pi->followup; - IF_HAS_KEYWORDS(last_rword = rword;) #if ENABLE_HUSH_IF - if (cond_code) { + if (cond_code != 0) { if (rword == RES_THEN) { /* if false; then ... fi has exitcode 0! */ G.last_exitcode = rcode = EXIT_SUCCESS; /* "if THEN cmd": skip cmd */ + debug_printf_exec("skipped THEN cmd because IF condition was false\n"); + last_rword = rword; continue; } } else { - if (rword == RES_ELSE || rword == RES_ELIF) { + if (rword == RES_ELSE + || (rword == RES_ELIF && last_rword != RES_ELIF) + ) { /* "if then ... ELSE/ELIF cmd": * skip cmd and all following ones */ + debug_printf_exec("skipped ELSE/ELIF branch because IF condition was true\n"); break; } + //if (rword == RES_THEN): "if THEN cmd", run cmd (fall through) } #endif + IF_HAS_KEYWORDS(last_rword = rword;) #if ENABLE_HUSH_LOOPS if (rword == RES_FOR) { /* && pi->num_cmds - always == 1 */ if (!for_lcur) { @@ -9943,7 +9949,7 @@ static int run_list(struct pipe *pi) ); /* TODO: which FNM_xxx flags to use? */ cond_code = (fnmatch(pattern, case_word, /*flags:*/ 0) != 0); - debug_printf_exec("fnmatch(pattern:'%s',str:'%s'):%d\n", + debug_printf_exec("cond_code=fnmatch(pattern:'%s',str:'%s'):%d\n", pattern, case_word, cond_code); free(pattern); if (cond_code == 0) { @@ -10069,8 +10075,10 @@ static int run_list(struct pipe *pi) /* Analyze how result affects subsequent commands */ #if ENABLE_HUSH_IF - if (rword == RES_IF || rword == RES_ELIF) + if (rword == RES_IF || rword == RES_ELIF) { + debug_printf_exec("cond_code=rcode:%d\n", rcode); cond_code = rcode; + } #endif check_jobs_and_continue: checkjobs(NULL, 0 /*(no pid to wait for)*/); @@ -10111,7 +10119,7 @@ static int run_list(struct pipe *pi) free(case_word); #endif debug_leave(); - debug_printf_exec("run_list lvl %d return %d\n", G.run_list_level + 1, rcode); + debug_printf_exec("run_list lvl %d return %d\n", G.run_list_level, rcode); return rcode; } diff --git a/shell/hush_test/hush-misc/elif1.right b/shell/hush_test/hush-misc/elif1.right new file mode 100644 index 0000000..36dc59f --- /dev/null +++ b/shell/hush_test/hush-misc/elif1.right @@ -0,0 +1,4 @@ +ELIF1 +ELIF2 +ELIF THEN +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 0000000..77b8a25 --- /dev/null +++ b/shell/hush_test/hush-misc/elif1.tests @@ -0,0 +1,6 @@ +if false; then + : +elif echo 'ELIF1'; echo 'ELIF2'; then + echo "ELIF THEN" +fi +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 0000000..8f2851f --- /dev/null +++ b/shell/hush_test/hush-misc/elif2.right @@ -0,0 +1,2 @@ +THEN +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 0000000..3e5876f --- /dev/null +++ b/shell/hush_test/hush-misc/elif2.tests @@ -0,0 +1,8 @@ +if true; then + echo "THEN" +elif echo "ELIF false"; false; then + echo "ELIF THEN" +else + echo "ELSE" +fi +echo "Ok:$?" -- cgit v1.1