diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2009-05-28 16:49:11 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2009-05-28 16:49:11 +0200 |
commit | e640cb4ad162422f71d267615da9cfe7ddfe6a2e (patch) | |
tree | 6d5a7a7b7f15bdf69ad05e9892708f8848f819a8 | |
parent | 5d7cca209085b31cc53df443d9439a0684646a77 (diff) | |
download | busybox-e640cb4ad162422f71d267615da9cfe7ddfe6a2e.tar.gz |
hush: fix bug 353 (wrong handling of \x in assignments)
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | shell/hush.c | 37 | ||||
-rw-r--r-- | shell/hush_test/hush-parsing/escape5.right | 9 | ||||
-rwxr-xr-x | shell/hush_test/hush-parsing/escape5.tests | 7 |
3 files changed, 31 insertions, 22 deletions
diff --git a/shell/hush.c b/shell/hush.c index cda1c2e74..1d4470efa 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -2055,10 +2055,10 @@ static char *expand_pseudo_dquoted(const char *str) * 'echo -$*-'. If you play here, you must run testsuite afterwards! */ static int expand_vars_to_list(o_string *output, int n, char *arg, char or_mask) { - /* or_mask is either 0 (normal case) or 0x80 - * (expansion of right-hand side of assignment == 1-element expand. - * It will also do no globbing, and thus we must not backslash-quote!) */ - + /* or_mask is either 0 (normal case) or 0x80 - + * expansion of right-hand side of assignment == 1-element expand. + * It will also do no globbing, and thus we must not backslash-quote! + */ char ored_ch; char *p; @@ -2412,6 +2412,7 @@ static char *expand_string_to_string(const char *str) bb_error_msg_and_die("BUG in varexp2"); /* actually, just move string 2*sizeof(char*) bytes back */ overlapping_strcpy((char*)list, list[0]); + unbackslash((char*)list); debug_printf_expand("string_to_string='%s'\n", (char*)list); return (char*)list; } @@ -3906,7 +3907,6 @@ static int run_list(struct pipe *pi) #endif #if ENABLE_HUSH_LOOPS struct pipe *loop_top = NULL; - char *for_varname = NULL; char **for_lcur = NULL; char **for_list = NULL; #endif @@ -4042,22 +4042,18 @@ static int run_list(struct pipe *pi) for_list = expand_strvec_to_strvec(vals); for_lcur = for_list; debug_print_strings("for_list", for_list); - for_varname = pi->cmds[0].argv[0]; - pi->cmds[0].argv[0] = NULL; } - free(pi->cmds[0].argv[0]); if (!*for_lcur) { /* "for" loop is over, clean up */ free(for_list); for_list = NULL; for_lcur = NULL; - pi->cmds[0].argv[0] = for_varname; break; } /* Insert next value from for_lcur */ /* note: *for_lcur already has quotes removed, $var expanded, etc */ - pi->cmds[0].argv[0] = xasprintf("%s=%s", for_varname, *for_lcur++); - pi->cmds[0].assignment_cnt = 1; + set_local_var(xasprintf("%s=%s", pi->cmds[0].argv[0], *for_lcur++), 0, 0); + continue; } if (rword == RES_IN) { continue; /* "for v IN list;..." - "in" has no cmds anyway */ @@ -4544,12 +4540,12 @@ static int done_word(o_string *word, struct parse_context *ctx) * Same with heredocs: * for <<\H delim is H; <<\\H, <<"\H", <<"\\H" - \H */ - unbackslash(ctx->pending_redirect->rd_filename); - /* Is it <<"HEREDOC"? */ - if (ctx->pending_redirect->rd_type == REDIRECT_HEREDOC - && word->o_quoted - ) { - ctx->pending_redirect->rd_dup |= HEREDOC_QUOTED; + if (ctx->pending_redirect->rd_type == REDIRECT_HEREDOC) { + unbackslash(ctx->pending_redirect->rd_filename); + /* Is it <<"HEREDOC"? */ + if (word->o_quoted) { + ctx->pending_redirect->rd_dup |= HEREDOC_QUOTED; + } } debug_printf_parse("word stored in rd_filename: '%s'\n", word->data); ctx->pending_redirect = NULL; @@ -5465,7 +5461,7 @@ static int parse_stream_dquoted(o_string *as_string, * "The backslash retains its special meaning [in "..."] * only when followed by one of the following characters: * $, `, ", \, or <newline>. A double quote may be quoted - * within double quotes by preceding it with a backslash. + * within double quotes by preceding it with a backslash." */ if (strchr("$`\"\\\n", next) != NULL) { ch = i_getch(input); @@ -5834,10 +5830,7 @@ static struct pipe *parse_stream(char **pstring, nommu_addchr(&ctx.as_string, ch); if (ch == '\'') break; - if (dest.o_assignment == NOT_ASSIGNMENT) - o_addqchr(&dest, ch); - else - o_addchr(&dest, ch); + o_addqchr(&dest, ch); } break; case '"': diff --git a/shell/hush_test/hush-parsing/escape5.right b/shell/hush_test/hush-parsing/escape5.right new file mode 100644 index 000000000..3cdd393c7 --- /dev/null +++ b/shell/hush_test/hush-parsing/escape5.right @@ -0,0 +1,9 @@ +a\nb\nc\n +a +b +c +a\nb\nc\n +a +b +c +Done diff --git a/shell/hush_test/hush-parsing/escape5.tests b/shell/hush_test/hush-parsing/escape5.tests new file mode 100755 index 000000000..337a98ec7 --- /dev/null +++ b/shell/hush_test/hush-parsing/escape5.tests @@ -0,0 +1,7 @@ +v="a\nb\nc\n" +echo "$v" +printf "$v" +v='a\nb\nc\n' +echo "$v" +printf "$v" +echo Done |