aboutsummaryrefslogtreecommitdiff
path: root/shell
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2025-08-07 01:30:57 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2025-08-07 01:30:57 +0200
commit7648dc721e390bba5049e798d73e70c6180b366b (patch)
treece7f34a088ef10e5889c834ccedd4523f7e9541c /shell
parent558ef4962dd3adb9e63b4c0787f8d4902fc909d4 (diff)
downloadbusybox-w32-7648dc721e390bba5049e798d73e70c6180b366b.tar.gz
busybox-w32-7648dc721e390bba5049e798d73e70c6180b366b.tar.bz2
busybox-w32-7648dc721e390bba5049e798d73e70c6180b366b.zip
ash,hush: fix corner cases with backslash-newlines in heredocs
function old new delta fetch_heredocs 477 485 +8 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'shell')
-rw-r--r--shell/ash.c7
-rw-r--r--shell/ash_test/ash-heredoc/heredoc_bkslash_newline2a.right1
-rwxr-xr-xshell/ash_test/ash-heredoc/heredoc_bkslash_newline2a.tests4
-rw-r--r--shell/ash_test/ash-heredoc/heredoc_bkslash_newline3.right1
-rwxr-xr-xshell/ash_test/ash-heredoc/heredoc_bkslash_newline3.tests4
-rw-r--r--shell/ash_test/ash-heredoc/heredoc_bkslash_newline3a.right1
-rwxr-xr-xshell/ash_test/ash-heredoc/heredoc_bkslash_newline3a.tests4
-rw-r--r--shell/hush.c12
-rw-r--r--shell/hush_test/hush-heredoc/heredoc_bkslash_newline2a.right1
-rwxr-xr-xshell/hush_test/hush-heredoc/heredoc_bkslash_newline2a.tests4
-rw-r--r--shell/hush_test/hush-heredoc/heredoc_bkslash_newline3.right1
-rwxr-xr-xshell/hush_test/hush-heredoc/heredoc_bkslash_newline3.tests4
-rw-r--r--shell/hush_test/hush-heredoc/heredoc_bkslash_newline3a.right1
-rwxr-xr-xshell/hush_test/hush-heredoc/heredoc_bkslash_newline3a.tests4
14 files changed, 44 insertions, 5 deletions
diff --git a/shell/ash.c b/shell/ash.c
index 9cacdff64..bfd9aa53e 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -12735,21 +12735,22 @@ checkend: {
12735 12735
12736 if (striptabs) { 12736 if (striptabs) {
12737 while (c == '\t') 12737 while (c == '\t')
12738 c = pgetc(); 12738 c = pgetc_eatbnl(); /* dash does pgetc() */
12739 /* (see heredoc_bkslash_newline3a.tests) */
12739 } 12740 }
12740 12741
12741 markloc = out - (char *)stackblock(); 12742 markloc = out - (char *)stackblock();
12742 for (p = eofmark; STPUTC(c, out), *p; p++) { 12743 for (p = eofmark; STPUTC(c, out), *p; p++) {
12743 if (c != *p) 12744 if (c != *p)
12744 goto more_heredoc; 12745 goto more_heredoc;
12745 /* FIXME: fails for backslash-newlined terminator: 12746 /* dash still has this not fixed (as of 2025-08)
12746 * cat <<EOF 12747 * cat <<EOF
12747 * ... 12748 * ...
12748 * EO\ 12749 * EO\
12749 * F 12750 * F
12750 * (see heredoc_bkslash_newline2.tests) 12751 * (see heredoc_bkslash_newline2.tests)
12751 */ 12752 */
12752 c = pgetc(); 12753 c = pgetc_eatbnl(); /* dash does pgetc() */
12753 } 12754 }
12754 12755
12755 if (c == '\n' || c == PEOF) { 12756 if (c == '\n' || c == PEOF) {
diff --git a/shell/ash_test/ash-heredoc/heredoc_bkslash_newline2a.right b/shell/ash_test/ash-heredoc/heredoc_bkslash_newline2a.right
new file mode 100644
index 000000000..3d79316d7
--- /dev/null
+++ b/shell/ash_test/ash-heredoc/heredoc_bkslash_newline2a.right
@@ -0,0 +1 @@
Ok1
diff --git a/shell/ash_test/ash-heredoc/heredoc_bkslash_newline2a.tests b/shell/ash_test/ash-heredoc/heredoc_bkslash_newline2a.tests
new file mode 100755
index 000000000..eb2223031
--- /dev/null
+++ b/shell/ash_test/ash-heredoc/heredoc_bkslash_newline2a.tests
@@ -0,0 +1,4 @@
1cat <<-EOF
2 Ok1
3 EO\
4F
diff --git a/shell/ash_test/ash-heredoc/heredoc_bkslash_newline3.right b/shell/ash_test/ash-heredoc/heredoc_bkslash_newline3.right
new file mode 100644
index 000000000..3d79316d7
--- /dev/null
+++ b/shell/ash_test/ash-heredoc/heredoc_bkslash_newline3.right
@@ -0,0 +1 @@
Ok1
diff --git a/shell/ash_test/ash-heredoc/heredoc_bkslash_newline3.tests b/shell/ash_test/ash-heredoc/heredoc_bkslash_newline3.tests
new file mode 100755
index 000000000..de21132d1
--- /dev/null
+++ b/shell/ash_test/ash-heredoc/heredoc_bkslash_newline3.tests
@@ -0,0 +1,4 @@
1cat <<EOF
2Ok1
3\
4EOF
diff --git a/shell/ash_test/ash-heredoc/heredoc_bkslash_newline3a.right b/shell/ash_test/ash-heredoc/heredoc_bkslash_newline3a.right
new file mode 100644
index 000000000..3d79316d7
--- /dev/null
+++ b/shell/ash_test/ash-heredoc/heredoc_bkslash_newline3a.right
@@ -0,0 +1 @@
Ok1
diff --git a/shell/ash_test/ash-heredoc/heredoc_bkslash_newline3a.tests b/shell/ash_test/ash-heredoc/heredoc_bkslash_newline3a.tests
new file mode 100755
index 000000000..da3860804
--- /dev/null
+++ b/shell/ash_test/ash-heredoc/heredoc_bkslash_newline3a.tests
@@ -0,0 +1,4 @@
1cat <<-EOF
2Ok1
3 \
4 EOF
diff --git a/shell/hush.c b/shell/hush.c
index 6129a087b..0b8da5e2d 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -4639,7 +4639,15 @@ static char *fetch_till_str(o_string *as_string,
4639 past_EOL = heredoc.length; 4639 past_EOL = heredoc.length;
4640 /* Get 1st char of next line, possibly skipping leading tabs */ 4640 /* Get 1st char of next line, possibly skipping leading tabs */
4641 do { 4641 do {
4642 ch = i_getch(input); 4642 if (heredoc_flags & HEREDOC_QUOTED)
4643 ch = i_getch(input);
4644 else { /* see heredoc_bkslash_newline3a.tests:
4645 * cat <<-EOF
4646 * <tab>\
4647 * <tab>EOF
4648 */
4649 ch = i_getch_and_eat_bkslash_nl(input);
4650 }
4643 if (ch != EOF) 4651 if (ch != EOF)
4644 nommu_addchr(as_string, ch); 4652 nommu_addchr(as_string, ch);
4645 } while ((heredoc_flags & HEREDOC_SKIPTABS) && ch == '\t'); 4653 } while ((heredoc_flags & HEREDOC_SKIPTABS) && ch == '\t');
@@ -4665,7 +4673,7 @@ static char *fetch_till_str(o_string *as_string,
4665 prev = 0; /* not '\' */ 4673 prev = 0; /* not '\' */
4666 continue; 4674 continue;
4667 } 4675 }
4668 } 4676 } /* if (\n or EOF) */
4669 if (ch == EOF) { 4677 if (ch == EOF) {
4670 o_free(&heredoc); 4678 o_free(&heredoc);
4671 return NULL; /* error */ 4679 return NULL; /* error */
diff --git a/shell/hush_test/hush-heredoc/heredoc_bkslash_newline2a.right b/shell/hush_test/hush-heredoc/heredoc_bkslash_newline2a.right
new file mode 100644
index 000000000..3d79316d7
--- /dev/null
+++ b/shell/hush_test/hush-heredoc/heredoc_bkslash_newline2a.right
@@ -0,0 +1 @@
Ok1
diff --git a/shell/hush_test/hush-heredoc/heredoc_bkslash_newline2a.tests b/shell/hush_test/hush-heredoc/heredoc_bkslash_newline2a.tests
new file mode 100755
index 000000000..eb2223031
--- /dev/null
+++ b/shell/hush_test/hush-heredoc/heredoc_bkslash_newline2a.tests
@@ -0,0 +1,4 @@
1cat <<-EOF
2 Ok1
3 EO\
4F
diff --git a/shell/hush_test/hush-heredoc/heredoc_bkslash_newline3.right b/shell/hush_test/hush-heredoc/heredoc_bkslash_newline3.right
new file mode 100644
index 000000000..3d79316d7
--- /dev/null
+++ b/shell/hush_test/hush-heredoc/heredoc_bkslash_newline3.right
@@ -0,0 +1 @@
Ok1
diff --git a/shell/hush_test/hush-heredoc/heredoc_bkslash_newline3.tests b/shell/hush_test/hush-heredoc/heredoc_bkslash_newline3.tests
new file mode 100755
index 000000000..de21132d1
--- /dev/null
+++ b/shell/hush_test/hush-heredoc/heredoc_bkslash_newline3.tests
@@ -0,0 +1,4 @@
1cat <<EOF
2Ok1
3\
4EOF
diff --git a/shell/hush_test/hush-heredoc/heredoc_bkslash_newline3a.right b/shell/hush_test/hush-heredoc/heredoc_bkslash_newline3a.right
new file mode 100644
index 000000000..3d79316d7
--- /dev/null
+++ b/shell/hush_test/hush-heredoc/heredoc_bkslash_newline3a.right
@@ -0,0 +1 @@
Ok1
diff --git a/shell/hush_test/hush-heredoc/heredoc_bkslash_newline3a.tests b/shell/hush_test/hush-heredoc/heredoc_bkslash_newline3a.tests
new file mode 100755
index 000000000..da3860804
--- /dev/null
+++ b/shell/hush_test/hush-heredoc/heredoc_bkslash_newline3a.tests
@@ -0,0 +1,4 @@
1cat <<-EOF
2Ok1
3 \
4 EOF