diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2009-05-28 16:49:11 +0200 |
---|---|---|
committer | Mike Frysinger <vapier@gentoo.org> | 2009-07-22 05:19:08 -0400 |
commit | 078d55028e4f4e9e4ba9216580a37778c40eca5c (patch) | |
tree | 6d8a625f7fe3059908fb4372dcf627f4bb3a3104 | |
parent | bbc31e5f3cb2482f752ab6251b1d7491b5ea73eb (diff) | |
download | busybox-w32-078d55028e4f4e9e4ba9216580a37778c40eca5c.tar.gz busybox-w32-078d55028e4f4e9e4ba9216580a37778c40eca5c.tar.bz2 busybox-w32-078d55028e4f4e9e4ba9216580a37778c40eca5c.zip |
hush: fix bug 353 (wrong handling of \x in assignments)
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
-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 d067e919d..386307720 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -2053,10 +2053,10 @@ static char *expand_pseudo_dquoted(const char *str) | |||
2053 | * 'echo -$*-'. If you play here, you must run testsuite afterwards! */ | 2053 | * 'echo -$*-'. If you play here, you must run testsuite afterwards! */ |
2054 | static int expand_vars_to_list(o_string *output, int n, char *arg, char or_mask) | 2054 | static int expand_vars_to_list(o_string *output, int n, char *arg, char or_mask) |
2055 | { | 2055 | { |
2056 | /* or_mask is either 0 (normal case) or 0x80 | 2056 | /* or_mask is either 0 (normal case) or 0x80 - |
2057 | * (expansion of right-hand side of assignment == 1-element expand. | 2057 | * expansion of right-hand side of assignment == 1-element expand. |
2058 | * It will also do no globbing, and thus we must not backslash-quote!) */ | 2058 | * It will also do no globbing, and thus we must not backslash-quote! |
2059 | 2059 | */ | |
2060 | char ored_ch; | 2060 | char ored_ch; |
2061 | char *p; | 2061 | char *p; |
2062 | 2062 | ||
@@ -2410,6 +2410,7 @@ static char *expand_string_to_string(const char *str) | |||
2410 | bb_error_msg_and_die("BUG in varexp2"); | 2410 | bb_error_msg_and_die("BUG in varexp2"); |
2411 | /* actually, just move string 2*sizeof(char*) bytes back */ | 2411 | /* actually, just move string 2*sizeof(char*) bytes back */ |
2412 | overlapping_strcpy((char*)list, list[0]); | 2412 | overlapping_strcpy((char*)list, list[0]); |
2413 | unbackslash((char*)list); | ||
2413 | debug_printf_expand("string_to_string='%s'\n", (char*)list); | 2414 | debug_printf_expand("string_to_string='%s'\n", (char*)list); |
2414 | return (char*)list; | 2415 | return (char*)list; |
2415 | } | 2416 | } |
@@ -3871,7 +3872,6 @@ static int run_list(struct pipe *pi) | |||
3871 | #endif | 3872 | #endif |
3872 | #if ENABLE_HUSH_LOOPS | 3873 | #if ENABLE_HUSH_LOOPS |
3873 | struct pipe *loop_top = NULL; | 3874 | struct pipe *loop_top = NULL; |
3874 | char *for_varname = NULL; | ||
3875 | char **for_lcur = NULL; | 3875 | char **for_lcur = NULL; |
3876 | char **for_list = NULL; | 3876 | char **for_list = NULL; |
3877 | #endif | 3877 | #endif |
@@ -4007,22 +4007,18 @@ static int run_list(struct pipe *pi) | |||
4007 | for_list = expand_strvec_to_strvec(vals); | 4007 | for_list = expand_strvec_to_strvec(vals); |
4008 | for_lcur = for_list; | 4008 | for_lcur = for_list; |
4009 | debug_print_strings("for_list", for_list); | 4009 | debug_print_strings("for_list", for_list); |
4010 | for_varname = pi->cmds[0].argv[0]; | ||
4011 | pi->cmds[0].argv[0] = NULL; | ||
4012 | } | 4010 | } |
4013 | free(pi->cmds[0].argv[0]); | ||
4014 | if (!*for_lcur) { | 4011 | if (!*for_lcur) { |
4015 | /* "for" loop is over, clean up */ | 4012 | /* "for" loop is over, clean up */ |
4016 | free(for_list); | 4013 | free(for_list); |
4017 | for_list = NULL; | 4014 | for_list = NULL; |
4018 | for_lcur = NULL; | 4015 | for_lcur = NULL; |
4019 | pi->cmds[0].argv[0] = for_varname; | ||
4020 | break; | 4016 | break; |
4021 | } | 4017 | } |
4022 | /* Insert next value from for_lcur */ | 4018 | /* Insert next value from for_lcur */ |
4023 | /* note: *for_lcur already has quotes removed, $var expanded, etc */ | 4019 | /* note: *for_lcur already has quotes removed, $var expanded, etc */ |
4024 | pi->cmds[0].argv[0] = xasprintf("%s=%s", for_varname, *for_lcur++); | 4020 | set_local_var(xasprintf("%s=%s", pi->cmds[0].argv[0], *for_lcur++), 0, 0); |
4025 | pi->cmds[0].assignment_cnt = 1; | 4021 | continue; |
4026 | } | 4022 | } |
4027 | if (rword == RES_IN) { | 4023 | if (rword == RES_IN) { |
4028 | continue; /* "for v IN list;..." - "in" has no cmds anyway */ | 4024 | continue; /* "for v IN list;..." - "in" has no cmds anyway */ |
@@ -4509,12 +4505,12 @@ static int done_word(o_string *word, struct parse_context *ctx) | |||
4509 | * Same with heredocs: | 4505 | * Same with heredocs: |
4510 | * for <<\H delim is H; <<\\H, <<"\H", <<"\\H" - \H | 4506 | * for <<\H delim is H; <<\\H, <<"\H", <<"\\H" - \H |
4511 | */ | 4507 | */ |
4512 | unbackslash(ctx->pending_redirect->rd_filename); | 4508 | if (ctx->pending_redirect->rd_type == REDIRECT_HEREDOC) { |
4513 | /* Is it <<"HEREDOC"? */ | 4509 | unbackslash(ctx->pending_redirect->rd_filename); |
4514 | if (ctx->pending_redirect->rd_type == REDIRECT_HEREDOC | 4510 | /* Is it <<"HEREDOC"? */ |
4515 | && word->o_quoted | 4511 | if (word->o_quoted) { |
4516 | ) { | 4512 | ctx->pending_redirect->rd_dup |= HEREDOC_QUOTED; |
4517 | ctx->pending_redirect->rd_dup |= HEREDOC_QUOTED; | 4513 | } |
4518 | } | 4514 | } |
4519 | debug_printf_parse("word stored in rd_filename: '%s'\n", word->data); | 4515 | debug_printf_parse("word stored in rd_filename: '%s'\n", word->data); |
4520 | ctx->pending_redirect = NULL; | 4516 | ctx->pending_redirect = NULL; |
@@ -5433,7 +5429,7 @@ static int parse_stream_dquoted(o_string *as_string, | |||
5433 | * "The backslash retains its special meaning [in "..."] | 5429 | * "The backslash retains its special meaning [in "..."] |
5434 | * only when followed by one of the following characters: | 5430 | * only when followed by one of the following characters: |
5435 | * $, `, ", \, or <newline>. A double quote may be quoted | 5431 | * $, `, ", \, or <newline>. A double quote may be quoted |
5436 | * within double quotes by preceding it with a backslash. | 5432 | * within double quotes by preceding it with a backslash." |
5437 | */ | 5433 | */ |
5438 | if (strchr("$`\"\\\n", next) != NULL) { | 5434 | if (strchr("$`\"\\\n", next) != NULL) { |
5439 | ch = i_getch(input); | 5435 | ch = i_getch(input); |
@@ -5802,10 +5798,7 @@ static struct pipe *parse_stream(char **pstring, | |||
5802 | nommu_addchr(&ctx.as_string, ch); | 5798 | nommu_addchr(&ctx.as_string, ch); |
5803 | if (ch == '\'') | 5799 | if (ch == '\'') |
5804 | break; | 5800 | break; |
5805 | if (dest.o_assignment == NOT_ASSIGNMENT) | 5801 | o_addqchr(&dest, ch); |
5806 | o_addqchr(&dest, ch); | ||
5807 | else | ||
5808 | o_addchr(&dest, ch); | ||
5809 | } | 5802 | } |
5810 | break; | 5803 | break; |
5811 | case '"': | 5804 | 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 | ||