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>
This commit is contained in:
Denys Vlasenko 2018-07-24 14:03:18 +02:00
parent 474cb20555
commit dfc7394763
5 changed files with 28 additions and 2 deletions

View File

@ -0,0 +1 @@
Ok1

View File

@ -0,0 +1,4 @@
cat <<EOF
Ok1
EO\
F

View File

@ -4250,6 +4250,7 @@ static char *fetch_till_str(o_string *as_string,
if (ch == '\n' || ch == EOF) { if (ch == '\n' || ch == EOF) {
check_heredoc_end: check_heredoc_end:
if ((heredoc_flags & HEREDOC_QUOTED) || prev != '\\') { if ((heredoc_flags & HEREDOC_QUOTED) || prev != '\\') {
/* End-of-line, and not a line continuation */
if (strcmp(heredoc.data + past_EOL, word) == 0) { if (strcmp(heredoc.data + past_EOL, word) == 0) {
heredoc.data[past_EOL] = '\0'; heredoc.data[past_EOL] = '\0';
debug_printf_heredoc("parsed '%s' heredoc '%s'\n", word, heredoc.data); 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') if (ch == '\n')
goto check_heredoc_end; 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) { if (ch == EOF) {
o_free(&heredoc); o_free(&heredoc);
return NULL; return NULL; /* error */
} }
o_addchr(&heredoc, ch); o_addchr(&heredoc, ch);
nommu_addchr(as_string, ch); nommu_addchr(as_string, ch);
if (prev == '\\' && ch == '\\') if (prev == '\\' && ch == '\\')
/* Correctly handle foo\\<eol> (not a line cont.) */ /* Correctly handle foo\\<eol> (not a line cont.) */
prev = 0; /* not \ */ prev = 0; /* not '\' */
else else
prev = ch; prev = ch;
} }

View File

@ -0,0 +1 @@
Ok1

View File

@ -0,0 +1,4 @@
cat <<EOF
Ok1
EO\
F