aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--shell/ash.c37
-rw-r--r--shell/shell_common.c2
-rwxr-xr-xtestsuite/sh.tests6
3 files changed, 40 insertions, 5 deletions
diff --git a/shell/ash.c b/shell/ash.c
index 63eb4947c..87190c453 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -193,12 +193,14 @@
193//config: case-insensitive filename globbing. 193//config: case-insensitive filename globbing.
194//config: 194//config:
195//config:config ASH_IGNORE_CR 195//config:config ASH_IGNORE_CR
196//config: bool "Ignore CR in scripts" 196//config: bool "Ignore CR in CRLF line endings"
197//config: default y 197//config: default y
198//config: depends on (ASH || SH_IS_ASH || BASH_IS_ASH) && PLATFORM_MINGW32 198//config: depends on (ASH || SH_IS_ASH || BASH_IS_ASH) && PLATFORM_MINGW32
199//config: help 199//config: help
200//config: Allow CRs to be ignored when shell scripts are parsed. This 200//config: Allow CRs to be ignored when they appear in CRLF line endings
201//config: makes it possible to run scripts with CRLF line endings. 201//config: but not in other circumstances. This isn't a general-purpose
202//config: option: it only covers certain new cases which are under test.
203//config: Enabled by default. May be removed in future.
202//config: 204//config:
203//config:endif # ash options 205//config:endif # ash options
204 206
@@ -6806,6 +6808,9 @@ ifsbreakup(char *string, struct arglist *arglist)
6806 const char *ifs, *realifs; 6808 const char *ifs, *realifs;
6807 int ifsspc; 6809 int ifsspc;
6808 int nulonly; 6810 int nulonly;
6811#if ENABLE_ASH_IGNORE_CR
6812 int lshift = 0;
6813#endif
6809 6814
6810 start = string; 6815 start = string;
6811 if (ifslastp != NULL) { 6816 if (ifslastp != NULL) {
@@ -6816,7 +6821,33 @@ ifsbreakup(char *string, struct arglist *arglist)
6816 do { 6821 do {
6817 int afternul; 6822 int afternul;
6818 6823
6824#if ENABLE_ASH_IGNORE_CR
6825 /* Adjust region offsets for left-shifted string. */
6826 ifsp->begoff -= lshift;
6827 ifsp->endoff -= lshift;
6828#endif
6819 p = string + ifsp->begoff; 6829 p = string + ifsp->begoff;
6830#if ENABLE_ASH_IGNORE_CR
6831 if (ifsp->endoff > ifsp->begoff + 1) {
6832 /* Transform CRLF to LF. Skip regions having zero or
6833 * one characters: they can't contain CRLF. If the
6834 * region shrinks shift the rest of the string left. */
6835 int oldlen = ifsp->endoff - ifsp->begoff;
6836 int newlen = remove_cr(p, oldlen);
6837 int delta = oldlen - newlen;
6838
6839 if (delta > 0) {
6840 char *t = string + ifsp->endoff;
6841 char *s = string + ifsp->endoff - delta;
6842
6843 while (*t)
6844 *s++ = *t++;
6845 *s = '\0';
6846 lshift += delta;
6847 ifsp->endoff -= delta;
6848 }
6849 }
6850#endif
6820 afternul = nulonly; 6851 afternul = nulonly;
6821 nulonly = ifsp->nulonly; 6852 nulonly = ifsp->nulonly;
6822 ifs = nulonly ? nullstr : realifs; 6853 ifs = nulonly ? nullstr : realifs;
diff --git a/shell/shell_common.c b/shell/shell_common.c
index 399d5e684..c0dd32fb4 100644
--- a/shell/shell_common.c
+++ b/shell/shell_common.c
@@ -19,7 +19,7 @@
19#include "libbb.h" 19#include "libbb.h"
20#include "shell_common.h" 20#include "shell_common.h"
21 21
22#if !ENABLE_PLATFORM_MINGW32 22#if !ENABLE_PLATFORM_MINGW32 || ENABLE_ASH_IGNORE_CR
23const char defifsvar[] ALIGN1 = "IFS= \t\n"; 23const char defifsvar[] ALIGN1 = "IFS= \t\n";
24#else 24#else
25const char defifsvar[] ALIGN1 = "IFS= \t\n\r"; 25const char defifsvar[] ALIGN1 = "IFS= \t\n\r";
diff --git a/testsuite/sh.tests b/testsuite/sh.tests
index 872611a1b..6fc3ca104 100755
--- a/testsuite/sh.tests
+++ b/testsuite/sh.tests
@@ -89,8 +89,12 @@ IyEvYmluL3NoICAtIAplY2hvICJIZWxsbyB3b3JsZCIK
89" 89"
90rm -f shebang_leading_argument_trailing_space.sh 90rm -f shebang_leading_argument_trailing_space.sh
91 91
92testing "remove CRs from string being evaluated" \ 92testing "sh remove CRs from string being evaluated" \
93 "sh -c \"$(printf 'set -e\r\necho Hello world\r\n')\"" \ 93 "sh -c \"$(printf 'set -e\r\necho Hello world\r\n')\"" \
94 "Hello world\n" "" "" 94 "Hello world\n" "" ""
95 95
96testing "sh preserve lone CRs during field splitting" \
97 "sh input" \
98 "Hello\r world\n" "echo \$(printf \"Hello\\\\r\\\\r\\\\nworld\\\\r\\\\n\")" ""
99
96exit $FAILCOUNT 100exit $FAILCOUNT