ash: [PARSER] Recognise here-doc delimiters terminated by EOF

Upstream commit 1:

    Date: Wed, 26 Sep 2007 17:14:16 +0800
    [PARSER] Recognise here-doc delimiters terminated by EOF

    Previously dash required a <newline> character to be present in order for
    a here-document delimiter to be detected.  Allowing EOF in the absence of
    a <newline> to play the same purpose allows some intuitive scripts to
    succeed.  POSIX seems to be silence on this so this should be OK.

    Test case:

        eval 'cat <<- NOT
                test
        NOT'
        echo OK

    Old result:

        test
        NOTOK

    New result:

        test
        OK

Upstream commit 2:

    Date: Sat, 20 Oct 2007 18:49:31 +0800
    [PARSER] Fix here-doc corruption

    The change

        [PARSER] Recognise here-doc delimiters terminated by EOF

    introduced a regerssion whereby lines starting with eofmark but are not equal
    to eofmark would be corrupted.  This patch fixes it.

    Test case:

        cat << _ACEOF
        _ASBOX
        _ACEOF

    Old result:

        SASBOX

    New result:

        _ASBOX

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
diff --git a/shell/ash.c b/shell/ash.c
index 2cebfe2..e0828d4 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -11592,11 +11592,17 @@
 		if (c == *eofmark) {
 			if (pfgets(line, sizeof(line)) != NULL) {
 				char *p, *q;
+				int cc;
 
 				p = line;
-				for (q = eofmark + 1; *q && *p == *q; p++, q++)
-					continue;
-				if (*p == '\n' && *q == '\0') {
+				for (q = eofmark + 1;; p++, q++) {
+					cc = *p;
+					if (cc == '\n')
+						cc = 0;
+					if (!*q || cc != *q)
+						break;
+				}
+				if (cc == *q) {
 					c = PEOF;
 					nlnoprompt();
 				} else {
diff --git a/shell/ash_test/ash-heredoc/heredoc6.right b/shell/ash_test/ash-heredoc/heredoc6.right
new file mode 100644
index 0000000..5d0f077
--- /dev/null
+++ b/shell/ash_test/ash-heredoc/heredoc6.right
@@ -0,0 +1,2 @@
+test
+OK:0
diff --git a/shell/ash_test/ash-heredoc/heredoc6.tests b/shell/ash_test/ash-heredoc/heredoc6.tests
new file mode 100755
index 0000000..346f594
--- /dev/null
+++ b/shell/ash_test/ash-heredoc/heredoc6.tests
@@ -0,0 +1,4 @@
+eval 'cat <<- NOT
+test
+NOT'
+echo OK:$?
diff --git a/shell/ash_test/ash-heredoc/heredoc7.right b/shell/ash_test/ash-heredoc/heredoc7.right
new file mode 100644
index 0000000..5d9c6c6
--- /dev/null
+++ b/shell/ash_test/ash-heredoc/heredoc7.right
@@ -0,0 +1 @@
+_ASBOX
diff --git a/shell/ash_test/ash-heredoc/heredoc7.tests b/shell/ash_test/ash-heredoc/heredoc7.tests
new file mode 100755
index 0000000..abd5941
--- /dev/null
+++ b/shell/ash_test/ash-heredoc/heredoc7.tests
@@ -0,0 +1,3 @@
+cat << _ACEOF
+_ASBOX
+_ACEOF
diff --git a/shell/hush_test/hush-heredoc/heredoc6.right b/shell/hush_test/hush-heredoc/heredoc6.right
new file mode 100644
index 0000000..5d0f077
--- /dev/null
+++ b/shell/hush_test/hush-heredoc/heredoc6.right
@@ -0,0 +1,2 @@
+test
+OK:0
diff --git a/shell/hush_test/hush-heredoc/heredoc6.tests b/shell/hush_test/hush-heredoc/heredoc6.tests
new file mode 100755
index 0000000..346f594
--- /dev/null
+++ b/shell/hush_test/hush-heredoc/heredoc6.tests
@@ -0,0 +1,4 @@
+eval 'cat <<- NOT
+test
+NOT'
+echo OK:$?
diff --git a/shell/hush_test/hush-heredoc/heredoc7.right b/shell/hush_test/hush-heredoc/heredoc7.right
new file mode 100644
index 0000000..5d9c6c6
--- /dev/null
+++ b/shell/hush_test/hush-heredoc/heredoc7.right
@@ -0,0 +1 @@
+_ASBOX
diff --git a/shell/hush_test/hush-heredoc/heredoc7.tests b/shell/hush_test/hush-heredoc/heredoc7.tests
new file mode 100755
index 0000000..abd5941
--- /dev/null
+++ b/shell/hush_test/hush-heredoc/heredoc7.tests
@@ -0,0 +1,3 @@
+cat << _ACEOF
+_ASBOX
+_ACEOF