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 /shell | |
| parent | 5d66c8a602a4604d5683ad42f692dbae19fc1693 (diff) | |
| download | busybox-w32-b4cedd4c9ae0ea31986973b7b3e6956937aafa32.tar.gz busybox-w32-b4cedd4c9ae0ea31986973b7b3e6956937aafa32.tar.bz2 busybox-w32-b4cedd4c9ae0ea31986973b7b3e6956937aafa32.zip | |
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>
Diffstat (limited to 'shell')
| -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 | 1 | ||
| 2 | 2 | ||
| 3 | 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 @@ | |||
| 1 | { f() { echo $1; } } | ||
| 2 | f 1 | ||
| 3 | |||
| 4 | { f() ( echo $1; )} | ||
| 5 | f 2 | ||
| 6 | |||
| 7 | { f()(echo $1)} | ||
| 8 | 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) | |||
| 4469 | } else | 4469 | } else |
| 4470 | # endif | 4470 | # endif |
| 4471 | /* Is it a place where keyword can appear? */ | 4471 | /* Is it a place where keyword can appear? */ |
| 4472 | if (!command->argv /* if it's the first word of command... */ | 4472 | //FIXME: this is wrong, it allows invalid syntax: { echo t; } if true; then echo YES; fi |
| 4473 | if ((!command->argv /* if it's the first word of command... */ | ||
| 4474 | # if ENABLE_HUSH_FUNCTIONS | ||
| 4475 | || command->cmd_type == CMD_FUNCDEF /* ^^^ or after FUNC() {} */ | ||
| 4476 | # endif | ||
| 4477 | ) | ||
| 4473 | && !ctx->word.has_quoted_part /* ""WORD never matches any keywords */ | 4478 | && !ctx->word.has_quoted_part /* ""WORD never matches any keywords */ |
| 4474 | && !command->redirects /* no redirects yet... disallows: </dev/null if true; then... */ | 4479 | && !command->redirects /* no redirects yet... disallows: </dev/null if true; then... */ |
| 4475 | # if ENABLE_HUSH_LOOPS | 4480 | # if ENABLE_HUSH_LOOPS |
| @@ -6067,7 +6072,11 @@ static struct pipe *parse_stream(char **pstring, | |||
| 6067 | } else | 6072 | } else |
| 6068 | #endif | 6073 | #endif |
| 6069 | /* Are { and } special here? */ | 6074 | /* Are { and } special here? */ |
| 6070 | if (ctx.command->argv /* WORD [WORD]{... - non-special */ | 6075 | if ((ctx.command->argv /* WORD [WORD]{... - non-special */ |
| 6076 | #if ENABLE_HUSH_FUNCTIONS | ||
| 6077 | && ctx.command->cmd_type != CMD_FUNCDEF /* ^^^ unless FUNC() {} */ | ||
| 6078 | #endif | ||
| 6079 | ) | ||
| 6071 | || !IS_NULL_WORD(ctx.word) /* WORD{... ""{... - non-special */ | 6080 | || !IS_NULL_WORD(ctx.word) /* WORD{... ""{... - non-special */ |
| 6072 | || (next != ';' /* }; - special */ | 6081 | || (next != ';' /* }; - special */ |
| 6073 | && next != ')' /* }) - special */ | 6082 | && 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 | 1 | ||
| 2 | 2 | ||
| 3 | 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 @@ | |||
| 1 | { f() { echo $1; } } | ||
| 2 | f 1 | ||
| 3 | |||
| 4 | { f() ( echo $1; )} | ||
| 5 | f 2 | ||
| 6 | |||
| 7 | { f()(echo $1)} | ||
| 8 | 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 | |||
