diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2018-07-23 16:31:21 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2018-07-23 16:31:21 +0200 |
commit | 3675c37b9b0bb4ba565b690b95b0b9c7d0ce8123 (patch) | |
tree | 889b8b684811dd9ff0dca01e6514136adb66a1e8 | |
parent | d73cdbf84c9c7d509baf69eb3256dcaf733f4d93 (diff) | |
download | busybox-w32-3675c37b9b0bb4ba565b690b95b0b9c7d0ce8123.tar.gz busybox-w32-3675c37b9b0bb4ba565b690b95b0b9c7d0ce8123.tar.bz2 busybox-w32-3675c37b9b0bb4ba565b690b95b0b9c7d0ce8123.zip |
hush: fix heredoc handling in the "cmd <<EOF ;<newline>" case
function old new delta
parse_stream 2759 2787 +28
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | shell/ash_test/ash-heredoc/heredocA.right | 1 | ||||
-rwxr-xr-x | shell/ash_test/ash-heredoc/heredocA.tests | 4 | ||||
-rw-r--r-- | shell/hush.c | 54 | ||||
-rw-r--r-- | shell/hush_test/hush-heredoc/heredoc9.right | 1 | ||||
-rwxr-xr-x | shell/hush_test/hush-heredoc/heredoc9.tests | 9 | ||||
-rw-r--r-- | shell/hush_test/hush-heredoc/heredocA.right | 1 | ||||
-rwxr-xr-x | shell/hush_test/hush-heredoc/heredocA.tests | 4 |
7 files changed, 50 insertions, 24 deletions
diff --git a/shell/ash_test/ash-heredoc/heredocA.right b/shell/ash_test/ash-heredoc/heredocA.right new file mode 100644 index 000000000..7326d9603 --- /dev/null +++ b/shell/ash_test/ash-heredoc/heredocA.right | |||
@@ -0,0 +1 @@ | |||
Ok | |||
diff --git a/shell/ash_test/ash-heredoc/heredocA.tests b/shell/ash_test/ash-heredoc/heredocA.tests new file mode 100755 index 000000000..440aaf906 --- /dev/null +++ b/shell/ash_test/ash-heredoc/heredocA.tests | |||
@@ -0,0 +1,4 @@ | |||
1 | { cat <<EOF ; | ||
2 | Ok | ||
3 | EOF | ||
4 | } | ||
diff --git a/shell/hush.c b/shell/hush.c index 89e06df4d..130c8e958 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -439,21 +439,22 @@ | |||
439 | 439 | ||
440 | /* If you comment out one of these below, it will be #defined later | 440 | /* If you comment out one of these below, it will be #defined later |
441 | * to perform debug printfs to stderr: */ | 441 | * to perform debug printfs to stderr: */ |
442 | #define debug_printf(...) do {} while (0) | 442 | #define debug_printf(...) do {} while (0) |
443 | /* Finer-grained debug switches */ | 443 | /* Finer-grained debug switches */ |
444 | #define debug_printf_parse(...) do {} while (0) | 444 | #define debug_printf_parse(...) do {} while (0) |
445 | #define debug_print_tree(a, b) do {} while (0) | 445 | #define debug_printf_heredoc(...) do {} while (0) |
446 | #define debug_printf_exec(...) do {} while (0) | 446 | #define debug_print_tree(a, b) do {} while (0) |
447 | #define debug_printf_env(...) do {} while (0) | 447 | #define debug_printf_exec(...) do {} while (0) |
448 | #define debug_printf_jobs(...) do {} while (0) | 448 | #define debug_printf_env(...) do {} while (0) |
449 | #define debug_printf_expand(...) do {} while (0) | 449 | #define debug_printf_jobs(...) do {} while (0) |
450 | #define debug_printf_varexp(...) do {} while (0) | 450 | #define debug_printf_expand(...) do {} while (0) |
451 | #define debug_printf_glob(...) do {} while (0) | 451 | #define debug_printf_varexp(...) do {} while (0) |
452 | #define debug_printf_redir(...) do {} while (0) | 452 | #define debug_printf_glob(...) do {} while (0) |
453 | #define debug_printf_list(...) do {} while (0) | 453 | #define debug_printf_redir(...) do {} while (0) |
454 | #define debug_printf_subst(...) do {} while (0) | 454 | #define debug_printf_list(...) do {} while (0) |
455 | #define debug_printf_prompt(...) do {} while (0) | 455 | #define debug_printf_subst(...) do {} while (0) |
456 | #define debug_printf_clean(...) do {} while (0) | 456 | #define debug_printf_prompt(...) do {} while (0) |
457 | #define debug_printf_clean(...) do {} while (0) | ||
457 | 458 | ||
458 | #define ERR_PTR ((void*)(long)1) | 459 | #define ERR_PTR ((void*)(long)1) |
459 | 460 | ||
@@ -1219,6 +1220,10 @@ static const struct built_in_command bltins2[] = { | |||
1219 | # define debug_printf_parse(...) (indent(), fdprintf(2, __VA_ARGS__)) | 1220 | # define debug_printf_parse(...) (indent(), fdprintf(2, __VA_ARGS__)) |
1220 | #endif | 1221 | #endif |
1221 | 1222 | ||
1223 | #ifndef debug_printf_heredoc | ||
1224 | # define debug_printf_heredoc(...) (indent(), fdprintf(2, __VA_ARGS__)) | ||
1225 | #endif | ||
1226 | |||
1222 | #ifndef debug_printf_exec | 1227 | #ifndef debug_printf_exec |
1223 | #define debug_printf_exec(...) (indent(), fdprintf(2, __VA_ARGS__)) | 1228 | #define debug_printf_exec(...) (indent(), fdprintf(2, __VA_ARGS__)) |
1224 | #endif | 1229 | #endif |
@@ -4245,7 +4250,7 @@ static char *fetch_till_str(o_string *as_string, | |||
4245 | if ((heredoc_flags & HEREDOC_QUOTED) || prev != '\\') { | 4250 | if ((heredoc_flags & HEREDOC_QUOTED) || prev != '\\') { |
4246 | if (strcmp(heredoc.data + past_EOL, word) == 0) { | 4251 | if (strcmp(heredoc.data + past_EOL, word) == 0) { |
4247 | heredoc.data[past_EOL] = '\0'; | 4252 | heredoc.data[past_EOL] = '\0'; |
4248 | debug_printf_parse("parsed heredoc '%s'\n", heredoc.data); | 4253 | debug_printf_heredoc("parsed '%s' heredoc '%s'\n", word, heredoc.data); |
4249 | return heredoc.data; | 4254 | return heredoc.data; |
4250 | } | 4255 | } |
4251 | if (ch == '\n') { | 4256 | if (ch == '\n') { |
@@ -4295,13 +4300,14 @@ static int fetch_heredocs(int heredoc_cnt, struct parse_context *ctx, struct in_ | |||
4295 | int i; | 4300 | int i; |
4296 | struct command *cmd = pi->cmds; | 4301 | struct command *cmd = pi->cmds; |
4297 | 4302 | ||
4298 | debug_printf_parse("fetch_heredocs: num_cmds:%d cmd argv0:'%s'\n", | 4303 | debug_printf_heredoc("fetch_heredocs: num_cmds:%d cmd argv0:'%s'\n", |
4299 | pi->num_cmds, | 4304 | pi->num_cmds, |
4300 | cmd->argv ? cmd->argv[0] : "NONE"); | 4305 | cmd->argv ? cmd->argv[0] : "NONE" |
4306 | ); | ||
4301 | for (i = 0; i < pi->num_cmds; i++) { | 4307 | for (i = 0; i < pi->num_cmds; i++) { |
4302 | struct redir_struct *redir = cmd->redirects; | 4308 | struct redir_struct *redir = cmd->redirects; |
4303 | 4309 | ||
4304 | debug_printf_parse("fetch_heredocs: %d cmd argv0:'%s'\n", | 4310 | debug_printf_heredoc("fetch_heredocs: %d cmd argv0:'%s'\n", |
4305 | i, cmd->argv ? cmd->argv[0] : "NONE"); | 4311 | i, cmd->argv ? cmd->argv[0] : "NONE"); |
4306 | while (redir) { | 4312 | while (redir) { |
4307 | if (redir->rd_type == REDIRECT_HEREDOC) { | 4313 | if (redir->rd_type == REDIRECT_HEREDOC) { |
@@ -4325,11 +4331,9 @@ static int fetch_heredocs(int heredoc_cnt, struct parse_context *ctx, struct in_ | |||
4325 | } | 4331 | } |
4326 | pi = pi->next; | 4332 | pi = pi->next; |
4327 | } | 4333 | } |
4328 | #if 0 | ||
4329 | /* Should be 0. If it isn't, it's a parse error */ | 4334 | /* Should be 0. If it isn't, it's a parse error */ |
4330 | if (heredoc_cnt) | 4335 | if (HUSH_DEBUG && heredoc_cnt) |
4331 | bb_error_msg_and_die("heredoc BUG 2"); | 4336 | bb_error_msg_and_die("heredoc BUG 2"); |
4332 | #endif | ||
4333 | return 0; | 4337 | return 0; |
4334 | } | 4338 | } |
4335 | 4339 | ||
@@ -5200,7 +5204,9 @@ static struct pipe *parse_stream(char **pstring, | |||
5200 | * "case ... in <newline> word) ..." | 5204 | * "case ... in <newline> word) ..." |
5201 | */ | 5205 | */ |
5202 | if (IS_NULL_CMD(ctx.command) | 5206 | if (IS_NULL_CMD(ctx.command) |
5203 | && ctx.word.length == 0 && !ctx.word.has_quoted_part | 5207 | && ctx.word.length == 0 |
5208 | && !ctx.word.has_quoted_part | ||
5209 | && heredoc_cnt == 0 | ||
5204 | ) { | 5210 | ) { |
5205 | /* This newline can be ignored. But... | 5211 | /* This newline can be ignored. But... |
5206 | * Without check #1, interactive shell | 5212 | * Without check #1, interactive shell |
@@ -5228,7 +5234,7 @@ static struct pipe *parse_stream(char **pstring, | |||
5228 | } | 5234 | } |
5229 | /* Treat newline as a command separator. */ | 5235 | /* Treat newline as a command separator. */ |
5230 | done_pipe(&ctx, PIPE_SEQ); | 5236 | done_pipe(&ctx, PIPE_SEQ); |
5231 | debug_printf_parse("heredoc_cnt:%d\n", heredoc_cnt); | 5237 | debug_printf_heredoc("heredoc_cnt:%d\n", heredoc_cnt); |
5232 | if (heredoc_cnt) { | 5238 | if (heredoc_cnt) { |
5233 | if (fetch_heredocs(heredoc_cnt, &ctx, input)) { | 5239 | if (fetch_heredocs(heredoc_cnt, &ctx, input)) { |
5234 | goto parse_error; | 5240 | goto parse_error; |
@@ -5362,7 +5368,7 @@ static struct pipe *parse_stream(char **pstring, | |||
5362 | if (next == '<') { | 5368 | if (next == '<') { |
5363 | redir_style = REDIRECT_HEREDOC; | 5369 | redir_style = REDIRECT_HEREDOC; |
5364 | heredoc_cnt++; | 5370 | heredoc_cnt++; |
5365 | debug_printf_parse("++heredoc_cnt=%d\n", heredoc_cnt); | 5371 | debug_printf_heredoc("++heredoc_cnt=%d\n", heredoc_cnt); |
5366 | ch = i_getch(input); | 5372 | ch = i_getch(input); |
5367 | nommu_addchr(&ctx.as_string, ch); | 5373 | nommu_addchr(&ctx.as_string, ch); |
5368 | } else if (next == '>') { | 5374 | } else if (next == '>') { |
diff --git a/shell/hush_test/hush-heredoc/heredoc9.right b/shell/hush_test/hush-heredoc/heredoc9.right new file mode 100644 index 000000000..ce0136250 --- /dev/null +++ b/shell/hush_test/hush-heredoc/heredoc9.right | |||
@@ -0,0 +1 @@ | |||
hello | |||
diff --git a/shell/hush_test/hush-heredoc/heredoc9.tests b/shell/hush_test/hush-heredoc/heredoc9.tests new file mode 100755 index 000000000..96c227cc1 --- /dev/null +++ b/shell/hush_test/hush-heredoc/heredoc9.tests | |||
@@ -0,0 +1,9 @@ | |||
1 | echo hello >greeting | ||
2 | cat <<EOF && | ||
3 | $(cat greeting) | ||
4 | EOF | ||
5 | { | ||
6 | echo $? | ||
7 | cat greeting | ||
8 | } >/dev/null | ||
9 | rm greeting | ||
diff --git a/shell/hush_test/hush-heredoc/heredocA.right b/shell/hush_test/hush-heredoc/heredocA.right new file mode 100644 index 000000000..7326d9603 --- /dev/null +++ b/shell/hush_test/hush-heredoc/heredocA.right | |||
@@ -0,0 +1 @@ | |||
Ok | |||
diff --git a/shell/hush_test/hush-heredoc/heredocA.tests b/shell/hush_test/hush-heredoc/heredocA.tests new file mode 100755 index 000000000..440aaf906 --- /dev/null +++ b/shell/hush_test/hush-heredoc/heredocA.tests | |||
@@ -0,0 +1,4 @@ | |||
1 | { cat <<EOF ; | ||
2 | Ok | ||
3 | EOF | ||
4 | } | ||