aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2009-05-28 16:49:11 +0200
committerMike Frysinger <vapier@gentoo.org>2009-07-22 05:19:08 -0400
commit078d55028e4f4e9e4ba9216580a37778c40eca5c (patch)
tree6d8a625f7fe3059908fb4372dcf627f4bb3a3104
parentbbc31e5f3cb2482f752ab6251b1d7491b5ea73eb (diff)
downloadbusybox-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.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 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! */
2054static int expand_vars_to_list(o_string *output, int n, char *arg, char or_mask) 2054static 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 @@
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