diff options
| author | Denys Vlasenko <vda.linux@googlemail.com> | 2025-08-18 14:51:25 +0200 |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2025-08-18 14:52:46 +0200 |
| commit | b4cedd4c9ae0ea31986973b7b3e6956937aafa32 (patch) | |
| tree | eee598da3138713f4da32a7fa197a3b483f85a5f | |
| parent | 5d66c8a602a4604d5683ad42f692dbae19fc1693 (diff) | |
hush: fix several syntax corner cases with function definitions
function old new delta
parse_stream 3063 3075 +12
done_word 777 784 +7
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/0 up/down: 19/0) Total: 19 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
| -rw-r--r-- | shell/ash_test/ash-misc/func6.right | 3 | ||||
| -rwxr-xr-x | shell/ash_test/ash-misc/func6.tests | 8 | ||||
| -rw-r--r-- | shell/ash_test/ash-misc/func7.right | 1 | ||||
| -rwxr-xr-x | shell/ash_test/ash-misc/func7.tests | 1 | ||||
| -rw-r--r-- | shell/hush.c | 13 | ||||
| -rw-r--r-- | shell/hush_test/hush-misc/func6.right | 3 | ||||
| -rwxr-xr-x | shell/hush_test/hush-misc/func6.tests | 8 | ||||
| -rw-r--r-- | shell/hush_test/hush-misc/func7.right | 1 | ||||
| -rwxr-xr-x | shell/hush_test/hush-misc/func7.tests | 1 |
9 files changed, 37 insertions, 2 deletions
diff --git a/shell/ash_test/ash-misc/func6.right b/shell/ash_test/ash-misc/func6.right new file mode 100644 index 000000000..01e79c32a --- /dev/null +++ b/shell/ash_test/ash-misc/func6.right @@ -0,0 +1,3 @@ +1 +2 +3 diff --git a/shell/ash_test/ash-misc/func6.tests b/shell/ash_test/ash-misc/func6.tests new file mode 100755 index 000000000..5f1699c42 --- /dev/null +++ b/shell/ash_test/ash-misc/func6.tests @@ -0,0 +1,8 @@ +{ f() { echo $1; } } +f 1 + +{ f() ( echo $1; )} +f 2 + +{ f()(echo $1)} +f 3 diff --git a/shell/ash_test/ash-misc/func7.right b/shell/ash_test/ash-misc/func7.right new file mode 100644 index 000000000..7b24a35ff --- /dev/null +++ b/shell/ash_test/ash-misc/func7.right @@ -0,0 +1 @@ +Ok:0 diff --git a/shell/ash_test/ash-misc/func7.tests b/shell/ash_test/ash-misc/func7.tests new file mode 100755 index 000000000..f5e03b6e1 --- /dev/null +++ b/shell/ash_test/ash-misc/func7.tests @@ -0,0 +1 @@ +if f() { echo Ok:$?; } then f; fi diff --git a/shell/hush.c b/shell/hush.c index 8aa923e2e..226a6d68f 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -4469,7 +4469,12 @@ static int done_word(struct parse_context *ctx) } else # endif /* Is it a place where keyword can appear? */ - if (!command->argv /* if it's the first word of command... */ +//FIXME: this is wrong, it allows invalid syntax: { echo t; } if true; then echo YES; fi + if ((!command->argv /* if it's the first word of command... */ +# if ENABLE_HUSH_FUNCTIONS + || command->cmd_type == CMD_FUNCDEF /* ^^^ or after FUNC() {} */ +# endif + ) && !ctx->word.has_quoted_part /* ""WORD never matches any keywords */ && !command->redirects /* no redirects yet... disallows: </dev/null if true; then... */ # if ENABLE_HUSH_LOOPS @@ -6067,7 +6072,11 @@ static struct pipe *parse_stream(char **pstring, } else #endif /* Are { and } special here? */ - if (ctx.command->argv /* WORD [WORD]{... - non-special */ + if ((ctx.command->argv /* WORD [WORD]{... - non-special */ +#if ENABLE_HUSH_FUNCTIONS + && ctx.command->cmd_type != CMD_FUNCDEF /* ^^^ unless FUNC() {} */ +#endif + ) || !IS_NULL_WORD(ctx.word) /* WORD{... ""{... - non-special */ || (next != ';' /* }; - special */ && next != ')' /* }) - special */ diff --git a/shell/hush_test/hush-misc/func6.right b/shell/hush_test/hush-misc/func6.right new file mode 100644 index 000000000..01e79c32a --- /dev/null +++ b/shell/hush_test/hush-misc/func6.right @@ -0,0 +1,3 @@ +1 +2 +3 diff --git a/shell/hush_test/hush-misc/func6.tests b/shell/hush_test/hush-misc/func6.tests new file mode 100755 index 000000000..5f1699c42 --- /dev/null +++ b/shell/hush_test/hush-misc/func6.tests @@ -0,0 +1,8 @@ +{ f() { echo $1; } } +f 1 + +{ f() ( echo $1; )} +f 2 + +{ f()(echo $1)} +f 3 diff --git a/shell/hush_test/hush-misc/func7.right b/shell/hush_test/hush-misc/func7.right new file mode 100644 index 000000000..7b24a35ff --- /dev/null +++ b/shell/hush_test/hush-misc/func7.right @@ -0,0 +1 @@ +Ok:0 diff --git a/shell/hush_test/hush-misc/func7.tests b/shell/hush_test/hush-misc/func7.tests new file mode 100755 index 000000000..f5e03b6e1 --- /dev/null +++ b/shell/hush_test/hush-misc/func7.tests @@ -0,0 +1 @@ +if f() { echo Ok:$?; } then f; fi |
