diff options
-rw-r--r-- | shell/ash.c | 37 | ||||
-rw-r--r-- | shell/shell_common.c | 2 | ||||
-rwxr-xr-x | testsuite/sh.tests | 6 |
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 |
23 | const char defifsvar[] ALIGN1 = "IFS= \t\n"; | 23 | const char defifsvar[] ALIGN1 = "IFS= \t\n"; |
24 | #else | 24 | #else |
25 | const char defifsvar[] ALIGN1 = "IFS= \t\n\r"; | 25 | const 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 | " |
90 | rm -f shebang_leading_argument_trailing_space.sh | 90 | rm -f shebang_leading_argument_trailing_space.sh |
91 | 91 | ||
92 | testing "remove CRs from string being evaluated" \ | 92 | testing "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 | ||
96 | testing "sh preserve lone CRs during field splitting" \ | ||
97 | "sh input" \ | ||
98 | "Hello\r world\n" "echo \$(printf \"Hello\\\\r\\\\r\\\\nworld\\\\r\\\\n\")" "" | ||
99 | |||
96 | exit $FAILCOUNT | 100 | exit $FAILCOUNT |