From 0f018b30700989462de0a15b8285206d16170c1f Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sat, 29 Jul 2017 20:43:26 +0200 Subject: [PATCH] hush: fix handling of empty heredoc EOF marker function old new delta parse_stream 2609 2634 +25 Signed-off-by: Denys Vlasenko --- .../ash_test/ash-heredoc/heredoc_empty2.right | 4 ++ .../ash_test/ash-heredoc/heredoc_empty2.tests | 14 ++++++ shell/hush.c | 44 ++++++++++++------- .../hush-heredoc/heredoc_empty2.right | 4 ++ .../hush-heredoc/heredoc_empty2.tests | 14 ++++++ 5 files changed, 63 insertions(+), 17 deletions(-) create mode 100644 shell/ash_test/ash-heredoc/heredoc_empty2.right create mode 100755 shell/ash_test/ash-heredoc/heredoc_empty2.tests create mode 100644 shell/hush_test/hush-heredoc/heredoc_empty2.right create mode 100755 shell/hush_test/hush-heredoc/heredoc_empty2.tests diff --git a/shell/ash_test/ash-heredoc/heredoc_empty2.right b/shell/ash_test/ash-heredoc/heredoc_empty2.right new file mode 100644 index 000000000..e32c6ea58 --- /dev/null +++ b/shell/ash_test/ash-heredoc/heredoc_empty2.right @@ -0,0 +1,4 @@ +OK1 +Ok:0 +OK2 +Ok:0 diff --git a/shell/ash_test/ash-heredoc/heredoc_empty2.tests b/shell/ash_test/ash-heredoc/heredoc_empty2.tests new file mode 100755 index 000000000..20fc35fe9 --- /dev/null +++ b/shell/ash_test/ash-heredoc/heredoc_empty2.tests @@ -0,0 +1,14 @@ +unset a + +# Heredoc with empty delimiter +cat <<- "" + OK1 + +echo Ok:$? + +# Heredoc with empty delimiter +cat <<- "" + OK2 + + +echo Ok:$? diff --git a/shell/hush.c b/shell/hush.c index d0225edb9..0fae809b3 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -4001,24 +4001,34 @@ static char *fetch_till_str(o_string *as_string, ch = i_getch(input); if (ch != EOF) nommu_addchr(as_string, ch); - if ((ch == '\n' || ch == EOF) - && ((heredoc_flags & HEREDOC_QUOTED) || prev != '\\') - ) { - if (strcmp(heredoc.data + past_EOL, word) == 0) { - heredoc.data[past_EOL] = '\0'; - debug_printf_parse("parsed heredoc '%s'\n", heredoc.data); - return heredoc.data; - } - while (ch == '\n') { - o_addchr(&heredoc, ch); - prev = ch; + if (ch == '\n' || ch == EOF) { + check_heredoc_end: + if ((heredoc_flags & HEREDOC_QUOTED) || prev != '\\') { + if (strcmp(heredoc.data + past_EOL, word) == 0) { + heredoc.data[past_EOL] = '\0'; + debug_printf_parse("parsed heredoc '%s'\n", heredoc.data); + return heredoc.data; + } + if (ch == '\n') { + /* This is a new line. + * Remember position and backslash-escaping status. + */ + o_addchr(&heredoc, ch); + prev = ch; jump_in: - past_EOL = heredoc.length; - do { - ch = i_getch(input); - if (ch != EOF) - nommu_addchr(as_string, ch); - } while ((heredoc_flags & HEREDOC_SKIPTABS) && ch == '\t'); + past_EOL = heredoc.length; + /* Get 1st char of next line, possibly skipping leading tabs */ + do { + ch = i_getch(input); + if (ch != EOF) + nommu_addchr(as_string, ch); + } while ((heredoc_flags & HEREDOC_SKIPTABS) && ch == '\t'); + /* If this immediately ended the line, + * go back to end-of-line checks. + */ + if (ch == '\n') + goto check_heredoc_end; + } } } if (ch == EOF) { diff --git a/shell/hush_test/hush-heredoc/heredoc_empty2.right b/shell/hush_test/hush-heredoc/heredoc_empty2.right new file mode 100644 index 000000000..e32c6ea58 --- /dev/null +++ b/shell/hush_test/hush-heredoc/heredoc_empty2.right @@ -0,0 +1,4 @@ +OK1 +Ok:0 +OK2 +Ok:0 diff --git a/shell/hush_test/hush-heredoc/heredoc_empty2.tests b/shell/hush_test/hush-heredoc/heredoc_empty2.tests new file mode 100755 index 000000000..20fc35fe9 --- /dev/null +++ b/shell/hush_test/hush-heredoc/heredoc_empty2.tests @@ -0,0 +1,14 @@ +unset a + +# Heredoc with empty delimiter +cat <<- "" + OK1 + +echo Ok:$? + +# Heredoc with empty delimiter +cat <<- "" + OK2 + + +echo Ok:$? -- 2.25.1