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 /shell | |
| parent | 5d7cca209085b31cc53df443d9439a0684646a77 (diff) | |
| download | busybox-w32-e640cb4ad162422f71d267615da9cfe7ddfe6a2e.tar.gz busybox-w32-e640cb4ad162422f71d267615da9cfe7ddfe6a2e.tar.bz2 busybox-w32-e640cb4ad162422f71d267615da9cfe7ddfe6a2e.zip | |
hush: fix bug 353 (wrong handling of \x in assignments)
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'shell')
| -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) | |||
| 2055 | * 'echo -$*-'. If you play here, you must run testsuite afterwards! */ | 2055 | * 'echo -$*-'. If you play here, you must run testsuite afterwards! */ |
| 2056 | static int expand_vars_to_list(o_string *output, int n, char *arg, char or_mask) | 2056 | static int expand_vars_to_list(o_string *output, int n, char *arg, char or_mask) |
| 2057 | { | 2057 | { |
| 2058 | /* or_mask is either 0 (normal case) or 0x80 | 2058 | /* or_mask is either 0 (normal case) or 0x80 - |
| 2059 | * (expansion of right-hand side of assignment == 1-element expand. | 2059 | * expansion of right-hand side of assignment == 1-element expand. |
| 2060 | * It will also do no globbing, and thus we must not backslash-quote!) */ | 2060 | * It will also do no globbing, and thus we must not backslash-quote! |
| 2061 | 2061 | */ | |
| 2062 | char ored_ch; | 2062 | char ored_ch; |
| 2063 | char *p; | 2063 | char *p; |
| 2064 | 2064 | ||
| @@ -2412,6 +2412,7 @@ static char *expand_string_to_string(const char *str) | |||
| 2412 | bb_error_msg_and_die("BUG in varexp2"); | 2412 | bb_error_msg_and_die("BUG in varexp2"); |
| 2413 | /* actually, just move string 2*sizeof(char*) bytes back */ | 2413 | /* actually, just move string 2*sizeof(char*) bytes back */ |
| 2414 | overlapping_strcpy((char*)list, list[0]); | 2414 | overlapping_strcpy((char*)list, list[0]); |
| 2415 | unbackslash((char*)list); | ||
| 2415 | debug_printf_expand("string_to_string='%s'\n", (char*)list); | 2416 | debug_printf_expand("string_to_string='%s'\n", (char*)list); |
| 2416 | return (char*)list; | 2417 | return (char*)list; |
| 2417 | } | 2418 | } |
| @@ -3906,7 +3907,6 @@ static int run_list(struct pipe *pi) | |||
| 3906 | #endif | 3907 | #endif |
| 3907 | #if ENABLE_HUSH_LOOPS | 3908 | #if ENABLE_HUSH_LOOPS |
| 3908 | struct pipe *loop_top = NULL; | 3909 | struct pipe *loop_top = NULL; |
| 3909 | char *for_varname = NULL; | ||
| 3910 | char **for_lcur = NULL; | 3910 | char **for_lcur = NULL; |
| 3911 | char **for_list = NULL; | 3911 | char **for_list = NULL; |
| 3912 | #endif | 3912 | #endif |
| @@ -4042,22 +4042,18 @@ static int run_list(struct pipe *pi) | |||
| 4042 | for_list = expand_strvec_to_strvec(vals); | 4042 | for_list = expand_strvec_to_strvec(vals); |
| 4043 | for_lcur = for_list; | 4043 | for_lcur = for_list; |
| 4044 | debug_print_strings("for_list", for_list); | 4044 | debug_print_strings("for_list", for_list); |
| 4045 | for_varname = pi->cmds[0].argv[0]; | ||
| 4046 | pi->cmds[0].argv[0] = NULL; | ||
| 4047 | } | 4045 | } |
| 4048 | free(pi->cmds[0].argv[0]); | ||
| 4049 | if (!*for_lcur) { | 4046 | if (!*for_lcur) { |
| 4050 | /* "for" loop is over, clean up */ | 4047 | /* "for" loop is over, clean up */ |
| 4051 | free(for_list); | 4048 | free(for_list); |
| 4052 | for_list = NULL; | 4049 | for_list = NULL; |
| 4053 | for_lcur = NULL; | 4050 | for_lcur = NULL; |
| 4054 | pi->cmds[0].argv[0] = for_varname; | ||
| 4055 | break; | 4051 | break; |
| 4056 | } | 4052 | } |
| 4057 | /* Insert next value from for_lcur */ | 4053 | /* Insert next value from for_lcur */ |
| 4058 | /* note: *for_lcur already has quotes removed, $var expanded, etc */ | 4054 | /* note: *for_lcur already has quotes removed, $var expanded, etc */ |
| 4059 | pi->cmds[0].argv[0] = xasprintf("%s=%s", for_varname, *for_lcur++); | 4055 | set_local_var(xasprintf("%s=%s", pi->cmds[0].argv[0], *for_lcur++), 0, 0); |
| 4060 | pi->cmds[0].assignment_cnt = 1; | 4056 | continue; |
| 4061 | } | 4057 | } |
| 4062 | if (rword == RES_IN) { | 4058 | if (rword == RES_IN) { |
| 4063 | continue; /* "for v IN list;..." - "in" has no cmds anyway */ | 4059 | 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) | |||
| 4544 | * Same with heredocs: | 4540 | * Same with heredocs: |
| 4545 | * for <<\H delim is H; <<\\H, <<"\H", <<"\\H" - \H | 4541 | * for <<\H delim is H; <<\\H, <<"\H", <<"\\H" - \H |
| 4546 | */ | 4542 | */ |
| 4547 | unbackslash(ctx->pending_redirect->rd_filename); | 4543 | if (ctx->pending_redirect->rd_type == REDIRECT_HEREDOC) { |
| 4548 | /* Is it <<"HEREDOC"? */ | 4544 | unbackslash(ctx->pending_redirect->rd_filename); |
| 4549 | if (ctx->pending_redirect->rd_type == REDIRECT_HEREDOC | 4545 | /* Is it <<"HEREDOC"? */ |
| 4550 | && word->o_quoted | 4546 | if (word->o_quoted) { |
| 4551 | ) { | 4547 | ctx->pending_redirect->rd_dup |= HEREDOC_QUOTED; |
| 4552 | ctx->pending_redirect->rd_dup |= HEREDOC_QUOTED; | 4548 | } |
| 4553 | } | 4549 | } |
| 4554 | debug_printf_parse("word stored in rd_filename: '%s'\n", word->data); | 4550 | debug_printf_parse("word stored in rd_filename: '%s'\n", word->data); |
| 4555 | ctx->pending_redirect = NULL; | 4551 | ctx->pending_redirect = NULL; |
| @@ -5465,7 +5461,7 @@ static int parse_stream_dquoted(o_string *as_string, | |||
| 5465 | * "The backslash retains its special meaning [in "..."] | 5461 | * "The backslash retains its special meaning [in "..."] |
| 5466 | * only when followed by one of the following characters: | 5462 | * only when followed by one of the following characters: |
| 5467 | * $, `, ", \, or <newline>. A double quote may be quoted | 5463 | * $, `, ", \, or <newline>. A double quote may be quoted |
| 5468 | * within double quotes by preceding it with a backslash. | 5464 | * within double quotes by preceding it with a backslash." |
| 5469 | */ | 5465 | */ |
| 5470 | if (strchr("$`\"\\\n", next) != NULL) { | 5466 | if (strchr("$`\"\\\n", next) != NULL) { |
| 5471 | ch = i_getch(input); | 5467 | ch = i_getch(input); |
| @@ -5834,10 +5830,7 @@ static struct pipe *parse_stream(char **pstring, | |||
| 5834 | nommu_addchr(&ctx.as_string, ch); | 5830 | nommu_addchr(&ctx.as_string, ch); |
| 5835 | if (ch == '\'') | 5831 | if (ch == '\'') |
| 5836 | break; | 5832 | break; |
| 5837 | if (dest.o_assignment == NOT_ASSIGNMENT) | 5833 | o_addqchr(&dest, ch); |
| 5838 | o_addqchr(&dest, ch); | ||
| 5839 | else | ||
| 5840 | o_addchr(&dest, ch); | ||
| 5841 | } | 5834 | } |
| 5842 | break; | 5835 | break; |
| 5843 | case '"': | 5836 | 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 @@ | |||
| 1 | a\nb\nc\n | ||
| 2 | a | ||
| 3 | b | ||
| 4 | c | ||
| 5 | a\nb\nc\n | ||
| 6 | a | ||
| 7 | b | ||
| 8 | c | ||
| 9 | 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 @@ | |||
| 1 | v="a\nb\nc\n" | ||
| 2 | echo "$v" | ||
| 3 | printf "$v" | ||
| 4 | v='a\nb\nc\n' | ||
| 5 | echo "$v" | ||
| 6 | printf "$v" | ||
| 7 | echo Done | ||
