hush: echo \2>file fix
authorDenis Vlasenko <vda.linux@googlemail.com>
Wed, 8 Apr 2009 09:29:14 +0000 (09:29 -0000)
committerDenis Vlasenko <vda.linux@googlemail.com>
Wed, 8 Apr 2009 09:29:14 +0000 (09:29 -0000)
shell/hush.c
shell/hush_test/hush-misc/heredoc2.right
shell/hush_test/hush-misc/heredoc2.tests
shell/hush_test/hush-misc/heredoc3.right
shell/hush_test/hush-misc/heredoc3.tests
shell/hush_test/hush-misc/redir2.right [new file with mode: 0644]
shell/hush_test/hush-misc/redir2.tests [new file with mode: 0755]

index d5c90a262387aa2ab7df91f72e76176f3dc1e8a9..5594aaea463265d01c975d6be1770236e168c7f5 100644 (file)
@@ -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) {
index 66545ae76541d25ae8b608b5b0ac6b59ff089a7c..74110e3b52aa57659d228253ad720676abf276f6 100644 (file)
@@ -6,3 +6,4 @@ moo
  EOF-f
 EOF-f   f
 EOF-f 
+Ok
index 19d9c96814bdf6031e9c5eb8136c2555e243509b..e619bded1c4a77c24f29440319fa7c9c7a756a6a 100755 (executable)
@@ -9,3 +9,4 @@ echo `echo Hello World`
 EOF-f   f
 EOF-f 
 EOF-f
+echo Ok
index 9b114fabfb6d8a182356b91b37bf15c0da840310..6ed517f742e843c99df1d0f4f5386b42c14954c3 100644 (file)
@@ -6,3 +6,4 @@ moo
  EOF-f
 EOF-f   f
 EOF-f 
+Ok
index 6391e49f9695da093557519609d0fcdcc17dd36b..938577a8908d0b9ef1c7ad7c85fad5543555454c 100755 (executable)
@@ -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 (file)
index 0000000..7326d96
--- /dev/null
@@ -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 (executable)
index 0000000..81983ca
--- /dev/null
@@ -0,0 +1,2 @@
+echo NOT SHOWN \2>/dev/null
+echo Ok