diff options
-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 | ||