diff options
author | Denys Vlasenko | 2015-09-04 06:22:10 +0200 |
---|---|---|
committer | Denys Vlasenko | 2015-09-04 06:22:10 +0200 |
commit | b5be13ccd9ce2120468a381a5475955013c0f049 (patch) | |
tree | cf2b99e5a1fc91944dade4c72694f7704502d438 /shell | |
parent | 2156e228537065f04e5f862e186421df0db36612 (diff) | |
download | busybox-b5be13ccd9ce2120468a381a5475955013c0f049.zip busybox-b5be13ccd9ce2120468a381a5475955013c0f049.tar.gz |
hush: fix a nommu bug where a part of function body is lost if run in a pipe
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'shell')
-rw-r--r-- | shell/hush.c | 35 | ||||
-rw-r--r-- | shell/hush_test/hush-misc/nommu3.right | 2 | ||||
-rwxr-xr-x | shell/hush_test/hush-misc/nommu3.tests | 15 |
3 files changed, 42 insertions, 10 deletions
diff --git a/shell/hush.c b/shell/hush.c index 3ca0449..752080a 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -3161,11 +3161,29 @@ static int reserved_word(o_string *word, struct parse_context *ctx) old->command->group = ctx->list_head; old->command->cmd_type = CMD_NORMAL; # if !BB_MMU - o_addstr(&old->as_string, ctx->as_string.data); - o_free_unsafe(&ctx->as_string); - old->command->group_as_string = xstrdup(old->as_string.data); - debug_printf_parse("pop, remembering as:'%s'\n", - old->command->group_as_string); + /* At this point, the compound command's string is in + * ctx->as_string... except for the leading keyword! + * Consider this example: "echo a | if true; then echo a; fi" + * ctx->as_string will contain "true; then echo a; fi", + * with "if " remaining in old->as_string! + */ + { + char *str; + int len = old->as_string.length; + /* Concatenate halves */ + o_addstr(&old->as_string, ctx->as_string.data); + o_free_unsafe(&ctx->as_string); + /* Find where leading keyword starts in first half */ + str = old->as_string.data + len; + if (str > old->as_string.data) + str--; /* skip whitespace after keyword */ + while (str > old->as_string.data && isalpha(str[-1])) + str--; + /* Ugh, we're done with this horrid hack */ + old->command->group_as_string = xstrdup(str); + debug_printf_parse("pop, remembering as:'%s'\n", + old->command->group_as_string); + } # endif *ctx = *old; /* physical copy */ free(old); @@ -4248,7 +4266,7 @@ static struct pipe *parse_stream(char **pstring, pi = NULL; } #if !BB_MMU - debug_printf_parse("as_string '%s'\n", ctx.as_string.data); + debug_printf_parse("as_string1 '%s'\n", ctx.as_string.data); if (pstring) *pstring = ctx.as_string.data; else @@ -4399,7 +4417,7 @@ static struct pipe *parse_stream(char **pstring, ) { o_free(&dest); #if !BB_MMU - debug_printf_parse("as_string '%s'\n", ctx.as_string.data); + debug_printf_parse("as_string2 '%s'\n", ctx.as_string.data); if (pstring) *pstring = ctx.as_string.data; else @@ -4639,9 +4657,6 @@ static struct pipe *parse_stream(char **pstring, * with redirect_opt_num(), but bash doesn't do it. * "echo foo 2| cat" yields "foo 2". */ done_command(&ctx); -#if !BB_MMU - o_reset_to_empty_unquoted(&ctx.as_string); -#endif } goto new_cmd; case '(': diff --git a/shell/hush_test/hush-misc/nommu3.right b/shell/hush_test/hush-misc/nommu3.right new file mode 100644 index 0000000..da1534b --- /dev/null +++ b/shell/hush_test/hush-misc/nommu3.right @@ -0,0 +1,2 @@ +Ok +0 diff --git a/shell/hush_test/hush-misc/nommu3.tests b/shell/hush_test/hush-misc/nommu3.tests new file mode 100755 index 0000000..0aca67a --- /dev/null +++ b/shell/hush_test/hush-misc/nommu3.tests @@ -0,0 +1,15 @@ +#!/bin/sh + +func() +{ + while read p; do echo "$p"; done +} + +pipe_to_func() +{ + # We had a NOMMU bug which caused "echo Ok |" part ot be lost + echo Ok | func +} + +pipe_to_func | cat +echo $? |