diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2018-07-24 14:03:18 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2018-07-24 14:03:18 +0200 |
commit | dfc739476343244371636d58561f7b743faf50d6 (patch) | |
tree | 7e41ed6fa9688c819f4d525255402179af6e0d0f | |
parent | 474cb205554919e4d017b7aeb3722d6a4ffee41d (diff) | |
download | busybox-dfc739476343244371636d58561f7b743faf50d6.tar.gz |
hush: handle backslash-newline in heredoc terminators
function old new delta
fetch_heredocs 479 527 +48
(ash fails this test)
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
5 files changed, 28 insertions, 2 deletions
diff --git a/shell/ash_test/ash-heredoc/heredoc_bkslash_newline2.right b/shell/ash_test/ash-heredoc/heredoc_bkslash_newline2.right new file mode 100644 index 000000000..3d79316d7 --- /dev/null +++ b/shell/ash_test/ash-heredoc/heredoc_bkslash_newline2.right @@ -0,0 +1 @@ +Ok1 diff --git a/shell/ash_test/ash-heredoc/heredoc_bkslash_newline2.tests b/shell/ash_test/ash-heredoc/heredoc_bkslash_newline2.tests new file mode 100755 index 000000000..1d2a26504 --- /dev/null +++ b/shell/ash_test/ash-heredoc/heredoc_bkslash_newline2.tests @@ -0,0 +1,4 @@ +cat <<EOF +Ok1 +EO\ +F diff --git a/shell/hush.c b/shell/hush.c index 75bce337a..c26484b49 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -4250,6 +4250,7 @@ static char *fetch_till_str(o_string *as_string, if (ch == '\n' || ch == EOF) { check_heredoc_end: if ((heredoc_flags & HEREDOC_QUOTED) || prev != '\\') { + /* End-of-line, and not a line continuation */ if (strcmp(heredoc.data + past_EOL, word) == 0) { heredoc.data[past_EOL] = '\0'; debug_printf_heredoc("parsed '%s' heredoc '%s'\n", word, heredoc.data); @@ -4275,17 +4276,32 @@ static char *fetch_till_str(o_string *as_string, if (ch == '\n') goto check_heredoc_end; } + } else { + /* Backslash-line continuation in an unquoted + * heredoc. This does not need special handling + * for heredoc body (unquoted heredocs are + * expanded on "execution" and that would take + * care of this case too), but not the case + * of line continuation *in terminator*: + * cat <<EOF + * Ok1 + * EO\ + * F + */ + heredoc.data[--heredoc.length] = '\0'; + prev = 0; /* not '\' */ + continue; } } if (ch == EOF) { o_free(&heredoc); - return NULL; + return NULL; /* error */ } o_addchr(&heredoc, ch); nommu_addchr(as_string, ch); if (prev == '\\' && ch == '\\') /* Correctly handle foo\\<eol> (not a line cont.) */ - prev = 0; /* not \ */ + prev = 0; /* not '\' */ else prev = ch; } diff --git a/shell/hush_test/hush-heredoc/heredoc_bkslash_newline2.right b/shell/hush_test/hush-heredoc/heredoc_bkslash_newline2.right new file mode 100644 index 000000000..3d79316d7 --- /dev/null +++ b/shell/hush_test/hush-heredoc/heredoc_bkslash_newline2.right @@ -0,0 +1 @@ +Ok1 diff --git a/shell/hush_test/hush-heredoc/heredoc_bkslash_newline2.tests b/shell/hush_test/hush-heredoc/heredoc_bkslash_newline2.tests new file mode 100755 index 000000000..1d2a26504 --- /dev/null +++ b/shell/hush_test/hush-heredoc/heredoc_bkslash_newline2.tests @@ -0,0 +1,4 @@ +cat <<EOF +Ok1 +EO\ +F |