← Commit list

b5be13ccd

Denys Vlasenko
Denys Vlasenko
2015-09-04
SUCCESS Duration: 196s

Subject

hush: fix a nommu bug where a part of function body is lost if run in a pipe

Binary

No binary (build failed)

Architecture & Compiler Flags

Architecture: x86_64-linux-gnu Compiler: gcc (Ubuntu 11.4.0-1ubuntu1~22.04.3) 11.4.0

—

Build Log

(log yok)

Commit Diff GitHub →

shell/hush.c+25 -10
@@ -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 '(':
shell/hush_test/hush-misc/nommu3.right+2 -0
@@ -0,0 +1,2 @@
+Ok
+0
shell/hush_test/hush-misc/nommu3.tests+15 -0
@@ -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 $?