summaryrefslogtreecommitdiff
path: root/shell
diff options
context:
space:
mode:
authorDenys Vlasenko2009-05-28 16:49:11 +0200
committerDenys Vlasenko2009-05-28 16:49:11 +0200
commite640cb4ad162422f71d267615da9cfe7ddfe6a2e (patch)
tree6d5a7a7b7f15bdf69ad05e9892708f8848f819a8 /shell
parent5d7cca209085b31cc53df443d9439a0684646a77 (diff)
downloadbusybox-e640cb4ad162422f71d267615da9cfe7ddfe6a2e.zip
busybox-e640cb4ad162422f71d267615da9cfe7ddfe6a2e.tar.gz
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.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 cda1c2e..1d4470e 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -2055,10 +2055,10 @@ static char *expand_pseudo_dquoted(const char *str)
* 'echo -$*-'. If you play here, you must run testsuite afterwards! */
static int expand_vars_to_list(o_string *output, int n, char *arg, char or_mask)
{
- /* or_mask is either 0 (normal case) or 0x80
- * (expansion of right-hand side of assignment == 1-element expand.
- * It will also do no globbing, and thus we must not backslash-quote!) */
-
+ /* or_mask is either 0 (normal case) or 0x80 -
+ * expansion of right-hand side of assignment == 1-element expand.
+ * It will also do no globbing, and thus we must not backslash-quote!
+ */
char ored_ch;
char *p;
@@ -2412,6 +2412,7 @@ static char *expand_string_to_string(const char *str)
bb_error_msg_and_die("BUG in varexp2");
/* actually, just move string 2*sizeof(char*) bytes back */
overlapping_strcpy((char*)list, list[0]);
+ unbackslash((char*)list);
debug_printf_expand("string_to_string='%s'\n", (char*)list);
return (char*)list;
}
@@ -3906,7 +3907,6 @@ static int run_list(struct pipe *pi)
#endif
#if ENABLE_HUSH_LOOPS
struct pipe *loop_top = NULL;
- char *for_varname = NULL;
char **for_lcur = NULL;
char **for_list = NULL;
#endif
@@ -4042,22 +4042,18 @@ static int run_list(struct pipe *pi)
for_list = expand_strvec_to_strvec(vals);
for_lcur = for_list;
debug_print_strings("for_list", for_list);
- for_varname = pi->cmds[0].argv[0];
- pi->cmds[0].argv[0] = NULL;
}
- free(pi->cmds[0].argv[0]);
if (!*for_lcur) {
/* "for" loop is over, clean up */
free(for_list);
for_list = NULL;
for_lcur = NULL;
- pi->cmds[0].argv[0] = for_varname;
break;
}
/* Insert next value from for_lcur */
/* note: *for_lcur already has quotes removed, $var expanded, etc */
- pi->cmds[0].argv[0] = xasprintf("%s=%s", for_varname, *for_lcur++);
- pi->cmds[0].assignment_cnt = 1;
+ set_local_var(xasprintf("%s=%s", pi->cmds[0].argv[0], *for_lcur++), 0, 0);
+ continue;
}
if (rword == RES_IN) {
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)
* Same with heredocs:
* for <<\H delim is H; <<\\H, <<"\H", <<"\\H" - \H
*/
- unbackslash(ctx->pending_redirect->rd_filename);
- /* Is it <<"HEREDOC"? */
- if (ctx->pending_redirect->rd_type == REDIRECT_HEREDOC
- && word->o_quoted
- ) {
- ctx->pending_redirect->rd_dup |= HEREDOC_QUOTED;
+ if (ctx->pending_redirect->rd_type == REDIRECT_HEREDOC) {
+ unbackslash(ctx->pending_redirect->rd_filename);
+ /* Is it <<"HEREDOC"? */
+ if (word->o_quoted) {
+ ctx->pending_redirect->rd_dup |= HEREDOC_QUOTED;
+ }
}
debug_printf_parse("word stored in rd_filename: '%s'\n", word->data);
ctx->pending_redirect = NULL;
@@ -5465,7 +5461,7 @@ static int parse_stream_dquoted(o_string *as_string,
* "The backslash retains its special meaning [in "..."]
* only when followed by one of the following characters:
* $, `, ", \, or <newline>. A double quote may be quoted
- * within double quotes by preceding it with a backslash.
+ * within double quotes by preceding it with a backslash."
*/
if (strchr("$`\"\\\n", next) != NULL) {
ch = i_getch(input);
@@ -5834,10 +5830,7 @@ static struct pipe *parse_stream(char **pstring,
nommu_addchr(&ctx.as_string, ch);
if (ch == '\'')
break;
- if (dest.o_assignment == NOT_ASSIGNMENT)
- o_addqchr(&dest, ch);
- else
- o_addchr(&dest, ch);
+ o_addqchr(&dest, ch);
}
break;
case '"':
diff --git a/shell/hush_test/hush-parsing/escape5.right b/shell/hush_test/hush-parsing/escape5.right
new file mode 100644
index 0000000..3cdd393
--- /dev/null
+++ b/shell/hush_test/hush-parsing/escape5.right
@@ -0,0 +1,9 @@
+a\nb\nc\n
+a
+b
+c
+a\nb\nc\n
+a
+b
+c
+Done
diff --git a/shell/hush_test/hush-parsing/escape5.tests b/shell/hush_test/hush-parsing/escape5.tests
new file mode 100755
index 0000000..337a98e
--- /dev/null
+++ b/shell/hush_test/hush-parsing/escape5.tests
@@ -0,0 +1,7 @@
+v="a\nb\nc\n"
+echo "$v"
+printf "$v"
+v='a\nb\nc\n'
+echo "$v"
+printf "$v"
+echo Done