Suspicious BUG in hush, while 'elif' has more commands than 1, only the first command is executed
Denys Vlasenko
vda.linux at googlemail.com
Thu May 25 12:39:45 UTC 2023
Thanks for the report.
Fixed in git.
On Fri, May 19, 2023 at 9:07 AM vsfos <vsfos at qq.com> wrote:
>
> Tested on wsl ubuntu 22.04 and linux orangepi5 by executing scripts below:
>
> #!/bin/sh
> if false; then
> : nothing
> elif echo 'test-1'; echo 'test-2' ; echo 'test-3'; then
> echo "abcdefg-1"
> fi
> echo again
> if echo 'test-1'; echo 'test-2' ; echo 'test-3'; then
> echo "abcdefg-1"
> fi
>
> Output will be like below on hush:
> test-1
> again
> test-1
> test-2
> test-3
> abcdefg-1
>
> On bash, output will be
> test-1
> test-2
> test-3
> abcdefg-1
> again
> test-1
> test-2
> test-3
> abcdefg-1
>
> exec log:
> parse_and_run_stream: run_and_free_list
> run_and_free_list entered
> : run_list: 1st pipe with 1 cmds
> run_list start lvl 0
> : rword=0 cond_code=0 last_rword=17
> : run_pipe with 1 members
> run_pipe start: members:1
> : group:0 argv:'./test'
> : pipe member './test' ' run_pipe return -1 (1 children started)
> execing './test'
> parse_and_run_stream: run_and_free_list
> run_and_free_list entered
> : run_list: 1st pipe with 0 cmds
> run_list start lvl 0
> : rword=0 cond_code=0 last_rword=17
> run_list lvl 1 return 0
> run_and_free_list return 0
> parse_and_run_stream: run_and_free_list
> run_and_free_list entered
> : run_list: 1st pipe with 1 cmds
> run_list start lvl 0
> : rword=0 cond_code=0 last_rword=17
> : run_pipe with 1 members
> run_pipe start: members:1
> : group:71a768 argv:'NONE'
> non-subshell group
> : run_list
> run_list start lvl 1
> : rword=1 cond_code=0 last_rword=17
> : run_pipe with 1 members
> run_pipe start: members:1
> : group:0 argv:'false'
> : pipe member 'false' ' run_pipe return -1 (1 children started)
> execing 'false'
> : checkjobs exitcode 255
> : rword=2 cond_code=255 last_rword=1
> : rword=3 cond_code=255 last_rword=2
> : run_pipe with 1 members
> run_pipe start: members:1
> : group:0 argv:'echo'
> found builtin 'echo'
> : builtin 'echo' 'test-1'...
> test-1
> run_pipe return 0
> : builtin/func exitcode 0
> : rword=3 cond_code=0 last_rword=3
> run_list lvl 2 return 0
> run_pipe: return 0
> : builtin/func exitcode 0
> : rword=0 cond_code=0 last_rword=0
> run_list lvl 1 return 0
> run_and_free_list return 0
> parse_and_run_stream: run_and_free_list
> run_and_free_list entered
> : run_list: 1st pipe with 1 cmds
> run_list start lvl 0
> : rword=0 cond_code=0 last_rword=17
> : run_pipe with 1 members
> run_pipe start: members:1
> : group:0 argv:'echo'
> found builtin 'echo'
> : builtin 'echo' 'again'...
> again
> run_pipe return 0
> : builtin/func exitcode 0
> : rword=0 cond_code=0 last_rword=0
> run_list lvl 1 return 0
> run_and_free_list return 0
> parse_and_run_stream: run_and_free_list
> run_and_free_list entered
> : run_list: 1st pipe with 1 cmds
> run_list start lvl 0
> : rword=0 cond_code=0 last_rword=17
> : run_pipe with 1 members
> run_pipe start: members:1
> : group:71a768 argv:'NONE'
> non-subshell group
> : run_list
> run_list start lvl 1
> : rword=1 cond_code=0 last_rword=17
> : run_pipe with 1 members
> run_pipe start: members:1
> : group:0 argv:'echo'
> found builtin 'echo'
> : builtin 'echo' 'test-1'...
> test-1
> run_pipe return 0
> : builtin/func exitcode 0
> : rword=1 cond_code=0 last_rword=1
> : run_pipe with 1 members
> run_pipe start: members:1
> : group:0 argv:'echo'
> found builtin 'echo'
> : builtin 'echo' 'test-2'...
> test-2
> run_pipe return 0
> : builtin/func exitcode 0
> : rword=1 cond_code=0 last_rword=1
> : run_pipe with 1 members
> run_pipe start: members:1
> : group:0 argv:'echo'
> found builtin 'echo'
> : builtin 'echo' 'test-3'...
> test-3
> run_pipe return 0
> : builtin/func exitcode 0
> : rword=2 cond_code=0 last_rword=1
> : run_pipe with 1 members
> run_pipe start: members:1
> : group:0 argv:'echo'
> found builtin 'echo'
> : builtin 'echo' 'abcdefg-1'...
> abcdefg-1
> run_pipe return 0
> : builtin/func exitcode 0
> : rword=5 cond_code=0 last_rword=2
> : rword=0 cond_code=0 last_rword=5
> run_list lvl 2 return 0
> run_pipe: return 0
> : builtin/func exitcode 0
> : rword=0 cond_code=0 last_rword=0
> run_list lvl 1 return 0
> run_and_free_list return 0
> : checkjobs_and_fg_shell exitcode 0
> : rword=0 cond_code=0 last_rword=0
> run_list lvl 1 return 0
> run_and_free_list return 0
>
> From the log, after the echo 'test-1' command, elif exited.
> The exit point is at here in run_list function:
> #if ENABLE_HUSH_IF
> if (cond_code) {
> if (rword == RES_THEN) {
> /* if false; then ... fi has exitcode 0! */
> G.last_exitcode = rcode = EXIT_SUCCESS;
> /* "if <false> THEN cmd": skip cmd */
> continue;
> }
> } else {
> if (rword == RES_ELSE || rword == RES_ELIF) {
> /* "if <true> then ... ELSE/ELIF cmd":
> * skip cmd and all following ones */
> break; // <<<<---- here
> }
> }
> #endif
> Because echo returns 0, and current rword is elif.
> _______________________________________________
> busybox mailing list
> busybox at busybox.net
> http://lists.busybox.net/mailman/listinfo/busybox
More information about the busybox
mailing list