aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2009-05-28 16:49:11 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2009-05-28 16:49:11 +0200
commite640cb4ad162422f71d267615da9cfe7ddfe6a2e (patch)
tree6d5a7a7b7f15bdf69ad05e9892708f8848f819a8
parent5d7cca209085b31cc53df443d9439a0684646a77 (diff)
downloadbusybox-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>
-rw-r--r--shell/hush.c37
-rw-r--r--shell/hush_test/hush-parsing/escape5.right9
-rwxr-xr-xshell/hush_test/hush-parsing/escape5.tests7
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! */
2056static int expand_vars_to_list(o_string *output, int n, char *arg, char or_mask) 2056static 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 @@
1a\nb\nc\n
2a
3b
4c
5a\nb\nc\n
6a
7b
8c
9Done
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 @@
1v="a\nb\nc\n"
2echo "$v"
3printf "$v"
4v='a\nb\nc\n'
5echo "$v"
6printf "$v"
7echo Done