diff options
Diffstat (limited to 'shell/hush.c')
-rw-r--r-- | shell/hush.c | 29 |
1 files changed, 21 insertions, 8 deletions
diff --git a/shell/hush.c b/shell/hush.c index d5c90a262..5594aaea4 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) { |