summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko2009-04-08 09:29:14 +0000
committerDenis Vlasenko2009-04-08 09:29:14 +0000
commit3dfb035d8df33e59492e78a97bf42e961ba178e4 (patch)
tree78ce918f14531d99a0b95a205a7984823ed4ad6b
parentdf6f95cedf4fe621048647f869db45daa7e5975a (diff)
downloadbusybox-3dfb035d8df33e59492e78a97bf42e961ba178e4.zip
busybox-3dfb035d8df33e59492e78a97bf42e961ba178e4.tar.gz
hush: echo \2>file fix
-rw-r--r--shell/hush.c29
-rw-r--r--shell/hush_test/hush-misc/heredoc2.right1
-rwxr-xr-xshell/hush_test/hush-misc/heredoc2.tests1
-rw-r--r--shell/hush_test/hush-misc/heredoc3.right1
-rwxr-xr-xshell/hush_test/hush-misc/heredoc3.tests1
-rw-r--r--shell/hush_test/hush-misc/redir2.right1
-rwxr-xr-xshell/hush_test/hush-misc/redir2.tests2
7 files changed, 28 insertions, 8 deletions
diff --git a/shell/hush.c b/shell/hush.c
index d5c90a2..5594aae 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -4081,7 +4081,7 @@ static int parse_redirect(struct parse_context *ctx,
* the redirection expression. For example:
* echo \2>a
* writes the character 2 into file a"
- * I am not sure we do it right (and not sure we care)
+ * We are getting it right by setting ->o_quoted on any \<char>
*
* A -1 return means no valid number was found,
* the caller should use the appropriate default for this redirection.
@@ -4141,6 +4141,9 @@ static char *fetch_till_str(o_string *as_string,
}
}
+/* Look at entire parse tree for not-yet-loaded REDIRECT_HEREDOCs
+ * and load them all. There should be exactly heredoc_cnt of them.
+ */
static int fetch_heredocs(int heredoc_cnt, struct parse_context *ctx, struct in_str *input)
{
struct pipe *pi = ctx->list_head;
@@ -4161,14 +4164,18 @@ static int fetch_heredocs(int heredoc_cnt, struct parse_context *ctx, struct in_
if (redir->rd_type == REDIRECT_HEREDOC) {
char *p;
- if (heredoc_cnt <= 0)
+ if (heredoc_cnt <= 0) {
+ syntax("heredoc BUG 1");
return 1; /* error */
+ }
redir->rd_type = REDIRECT_HEREDOC2;
/* redir->dup is (ab)used to indicate <<- */
p = fetch_till_str(&ctx->as_string, input,
redir->rd_filename, redir->rd_dup & HEREDOC_SKIPTABS);
- if (!p)
- return 1; /* unexpected EOF */
+ if (!p) {
+ syntax("unexpected EOF in here document");
+ return 1;
+ }
free(redir->rd_filename);
redir->rd_filename = p;
heredoc_cnt--;
@@ -4180,6 +4187,8 @@ static int fetch_heredocs(int heredoc_cnt, struct parse_context *ctx, struct in_
pi = pi->next;
}
/* Should be 0. If it isn't, it's a parse error */
+ if (heredoc_cnt)
+ syntax("heredoc BUG 2");
return heredoc_cnt;
}
@@ -4673,12 +4682,12 @@ static int parse_stream_dquoted(o_string *as_string,
if (ch != EOF)
nommu_addchr(as_string, ch);
if (ch == dquote_end) { /* may be only '"' or EOF */
- dest->o_quoted = 1;
if (dest->o_assignment == NOT_ASSIGNMENT)
dest->o_escape ^= 1;
debug_printf_parse("parse_stream_dquoted return 0\n");
return 0;
}
+ /* note: can't move it above ch == dquote_end check! */
if (ch == EOF) {
syntax("unterminated \"");
debug_printf_parse("parse_stream_dquoted return 1: unterminated \"\n");
@@ -4787,6 +4796,7 @@ static struct pipe *parse_stream(char **pstring,
redir_type redir_style;
if (is_in_dquote) {
+ /* dest.o_quoted = 1; - already is (see below) */
if (parse_stream_dquoted(&ctx.as_string, &dest, input, '"')) {
goto parse_error;
}
@@ -4863,8 +4873,9 @@ static struct pipe *parse_stream(char **pstring,
done_pipe(&ctx, PIPE_SEQ);
debug_printf_parse("heredoc_cnt:%d\n", heredoc_cnt);
if (heredoc_cnt) {
- if (fetch_heredocs(heredoc_cnt, &ctx, input))
+ if (fetch_heredocs(heredoc_cnt, &ctx, input)) {
goto parse_error;
+ }
heredoc_cnt = 0;
}
dest.o_assignment = MAYBE_ASSIGNMENT;
@@ -4938,7 +4949,6 @@ static struct pipe *parse_stream(char **pstring,
i_getch(input);
/* note: we do not add it to &ctx.as_string */
}
-//TODO: go back one char?
nommu_addchr(&ctx.as_string, '\n');
} else {
o_addQchr(&dest, ch);
@@ -4951,8 +4961,11 @@ static struct pipe *parse_stream(char **pstring,
}
o_addchr(&dest, '\\');
ch = i_getch(input);
- o_addchr(&dest, ch);
nommu_addchr(&ctx.as_string, ch);
+ o_addchr(&dest, ch);
+ /* Example: echo Hello \2>file
+ * we need to know that word 2 is quoted */
+ dest.o_quoted = 1;
break;
case '$':
if (handle_dollar(&ctx.as_string, &dest, input) != 0) {
diff --git a/shell/hush_test/hush-misc/heredoc2.right b/shell/hush_test/hush-misc/heredoc2.right
index 66545ae..74110e3 100644
--- a/shell/hush_test/hush-misc/heredoc2.right
+++ b/shell/hush_test/hush-misc/heredoc2.right
@@ -6,3 +6,4 @@ moo
EOF-f
EOF-f f
EOF-f
+Ok
diff --git a/shell/hush_test/hush-misc/heredoc2.tests b/shell/hush_test/hush-misc/heredoc2.tests
index 19d9c96..e619bde 100755
--- a/shell/hush_test/hush-misc/heredoc2.tests
+++ b/shell/hush_test/hush-misc/heredoc2.tests
@@ -9,3 +9,4 @@ echo `echo Hello World`
EOF-f f
EOF-f
EOF-f
+echo Ok
diff --git a/shell/hush_test/hush-misc/heredoc3.right b/shell/hush_test/hush-misc/heredoc3.right
index 9b114fa..6ed517f 100644
--- a/shell/hush_test/hush-misc/heredoc3.right
+++ b/shell/hush_test/hush-misc/heredoc3.right
@@ -6,3 +6,4 @@ moo
EOF-f
EOF-f f
EOF-f
+Ok
diff --git a/shell/hush_test/hush-misc/heredoc3.tests b/shell/hush_test/hush-misc/heredoc3.tests
index 6391e49..938577a 100755
--- a/shell/hush_test/hush-misc/heredoc3.tests
+++ b/shell/hush_test/hush-misc/heredoc3.tests
@@ -9,3 +9,4 @@ echo `echo Hello World`
EOF-f f
EOF-f
EOF-f
+echo Ok
diff --git a/shell/hush_test/hush-misc/redir2.right b/shell/hush_test/hush-misc/redir2.right
new file mode 100644
index 0000000..7326d96
--- /dev/null
+++ b/shell/hush_test/hush-misc/redir2.right
@@ -0,0 +1 @@
+Ok
diff --git a/shell/hush_test/hush-misc/redir2.tests b/shell/hush_test/hush-misc/redir2.tests
new file mode 100755
index 0000000..81983ca
--- /dev/null
+++ b/shell/hush_test/hush-misc/redir2.tests
@@ -0,0 +1,2 @@
+echo NOT SHOWN \2>/dev/null
+echo Ok