diff options
author | Ron Yorston <rmy@pobox.com> | 2023-02-07 10:03:04 +0000 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2023-02-07 10:03:04 +0000 |
commit | 4b894b60ae377ee2a04ae209c14bb1e714ecf6f4 (patch) | |
tree | 8f42f36eb0a9dad2c712f7b0e07aff7dee059217 | |
parent | c49b8b7052bb1df3ed5f9aeba61a7965d9c77f83 (diff) | |
download | busybox-w32-4b894b60ae377ee2a04ae209c14bb1e714ecf6f4.tar.gz busybox-w32-4b894b60ae377ee2a04ae209c14bb1e714ecf6f4.tar.bz2 busybox-w32-4b894b60ae377ee2a04ae209c14bb1e714ecf6f4.zip |
ash: change CRLF handling
As noted in commit 2d848eba5 (ash: fix CRLF handling) all CRs are
removed when scripts are read. Allow an alternative approach
(configurable at build-time, enabled by default):
- Do not strip CRs from input.
- Treat CR as similar to space or tab in base syntax mode.
- Adjust pgetc_eatbnl() to handle backslash-CRLF in the same way
as backslash-LF.
With these changes scripts containing CRLF line endings are more
likely to work.
Adds 48-56 bytes.
(GitHub issue #285)
-rw-r--r-- | configs/mingw32_defconfig | 9 | ||||
-rw-r--r-- | configs/mingw64_defconfig | 9 | ||||
-rw-r--r-- | shell/ash.c | 44 |
3 files changed, 55 insertions, 7 deletions
diff --git a/configs/mingw32_defconfig b/configs/mingw32_defconfig index f4019afe6..78035dd25 100644 --- a/configs/mingw32_defconfig +++ b/configs/mingw32_defconfig | |||
@@ -1,7 +1,7 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Busybox version: 1.36.0.git | 3 | # Busybox version: 1.37.0.git |
4 | # Wed Oct 12 10:45:30 2022 | 4 | # Tue Feb 7 09:34:52 2023 |
5 | # | 5 | # |
6 | CONFIG_HAVE_DOT_CONFIG=y | 6 | CONFIG_HAVE_DOT_CONFIG=y |
7 | # CONFIG_PLATFORM_POSIX is not set | 7 | # CONFIG_PLATFORM_POSIX is not set |
@@ -145,6 +145,9 @@ CONFIG_LAST_SUPPORTED_WCHAR=0 | |||
145 | # CONFIG_UNICODE_BIDI_SUPPORT is not set | 145 | # CONFIG_UNICODE_BIDI_SUPPORT is not set |
146 | # CONFIG_UNICODE_NEUTRAL_TABLE is not set | 146 | # CONFIG_UNICODE_NEUTRAL_TABLE is not set |
147 | # CONFIG_UNICODE_PRESERVE_BROKEN is not set | 147 | # CONFIG_UNICODE_PRESERVE_BROKEN is not set |
148 | # CONFIG_LOOP_CONFIGURE is not set | ||
149 | # CONFIG_NO_LOOP_CONFIGURE is not set | ||
150 | CONFIG_TRY_LOOP_CONFIGURE=y | ||
148 | 151 | ||
149 | # | 152 | # |
150 | # Applets | 153 | # Applets |
@@ -1027,6 +1030,7 @@ CONFIG_DHCPD_LEASES_FILE="" | |||
1027 | # CONFIG_FEATURE_UDHCPC_ARPING is not set | 1030 | # CONFIG_FEATURE_UDHCPC_ARPING is not set |
1028 | # CONFIG_FEATURE_UDHCPC_SANITIZEOPT is not set | 1031 | # CONFIG_FEATURE_UDHCPC_SANITIZEOPT is not set |
1029 | CONFIG_UDHCPC_DEFAULT_SCRIPT="" | 1032 | CONFIG_UDHCPC_DEFAULT_SCRIPT="" |
1033 | CONFIG_UDHCPC6_DEFAULT_SCRIPT="" | ||
1030 | # CONFIG_UDHCPC6 is not set | 1034 | # CONFIG_UDHCPC6 is not set |
1031 | # CONFIG_FEATURE_UDHCPC6_RFC3646 is not set | 1035 | # CONFIG_FEATURE_UDHCPC6_RFC3646 is not set |
1032 | # CONFIG_FEATURE_UDHCPC6_RFC4704 is not set | 1036 | # CONFIG_FEATURE_UDHCPC6_RFC4704 is not set |
@@ -1163,6 +1167,7 @@ CONFIG_ASH_GETOPTS=y | |||
1163 | CONFIG_ASH_CMDCMD=y | 1167 | CONFIG_ASH_CMDCMD=y |
1164 | CONFIG_ASH_NOCONSOLE=y | 1168 | CONFIG_ASH_NOCONSOLE=y |
1165 | CONFIG_ASH_NOCASEGLOB=y | 1169 | CONFIG_ASH_NOCASEGLOB=y |
1170 | CONFIG_ASH_IGNORE_CR=y | ||
1166 | # CONFIG_CTTYHACK is not set | 1171 | # CONFIG_CTTYHACK is not set |
1167 | # CONFIG_HUSH is not set | 1172 | # CONFIG_HUSH is not set |
1168 | # CONFIG_SHELL_HUSH is not set | 1173 | # CONFIG_SHELL_HUSH is not set |
diff --git a/configs/mingw64_defconfig b/configs/mingw64_defconfig index bf8cc5452..1ef6024c1 100644 --- a/configs/mingw64_defconfig +++ b/configs/mingw64_defconfig | |||
@@ -1,7 +1,7 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Busybox version: 1.36.0.git | 3 | # Busybox version: 1.37.0.git |
4 | # Wed Oct 12 10:45:30 2022 | 4 | # Tue Feb 7 09:34:52 2023 |
5 | # | 5 | # |
6 | CONFIG_HAVE_DOT_CONFIG=y | 6 | CONFIG_HAVE_DOT_CONFIG=y |
7 | # CONFIG_PLATFORM_POSIX is not set | 7 | # CONFIG_PLATFORM_POSIX is not set |
@@ -145,6 +145,9 @@ CONFIG_LAST_SUPPORTED_WCHAR=0 | |||
145 | # CONFIG_UNICODE_BIDI_SUPPORT is not set | 145 | # CONFIG_UNICODE_BIDI_SUPPORT is not set |
146 | # CONFIG_UNICODE_NEUTRAL_TABLE is not set | 146 | # CONFIG_UNICODE_NEUTRAL_TABLE is not set |
147 | # CONFIG_UNICODE_PRESERVE_BROKEN is not set | 147 | # CONFIG_UNICODE_PRESERVE_BROKEN is not set |
148 | # CONFIG_LOOP_CONFIGURE is not set | ||
149 | # CONFIG_NO_LOOP_CONFIGURE is not set | ||
150 | CONFIG_TRY_LOOP_CONFIGURE=y | ||
148 | 151 | ||
149 | # | 152 | # |
150 | # Applets | 153 | # Applets |
@@ -1027,6 +1030,7 @@ CONFIG_DHCPD_LEASES_FILE="" | |||
1027 | # CONFIG_FEATURE_UDHCPC_ARPING is not set | 1030 | # CONFIG_FEATURE_UDHCPC_ARPING is not set |
1028 | # CONFIG_FEATURE_UDHCPC_SANITIZEOPT is not set | 1031 | # CONFIG_FEATURE_UDHCPC_SANITIZEOPT is not set |
1029 | CONFIG_UDHCPC_DEFAULT_SCRIPT="" | 1032 | CONFIG_UDHCPC_DEFAULT_SCRIPT="" |
1033 | CONFIG_UDHCPC6_DEFAULT_SCRIPT="" | ||
1030 | # CONFIG_UDHCPC6 is not set | 1034 | # CONFIG_UDHCPC6 is not set |
1031 | # CONFIG_FEATURE_UDHCPC6_RFC3646 is not set | 1035 | # CONFIG_FEATURE_UDHCPC6_RFC3646 is not set |
1032 | # CONFIG_FEATURE_UDHCPC6_RFC4704 is not set | 1036 | # CONFIG_FEATURE_UDHCPC6_RFC4704 is not set |
@@ -1163,6 +1167,7 @@ CONFIG_ASH_GETOPTS=y | |||
1163 | CONFIG_ASH_CMDCMD=y | 1167 | CONFIG_ASH_CMDCMD=y |
1164 | CONFIG_ASH_NOCONSOLE=y | 1168 | CONFIG_ASH_NOCONSOLE=y |
1165 | CONFIG_ASH_NOCASEGLOB=y | 1169 | CONFIG_ASH_NOCASEGLOB=y |
1170 | CONFIG_ASH_IGNORE_CR=y | ||
1166 | # CONFIG_CTTYHACK is not set | 1171 | # CONFIG_CTTYHACK is not set |
1167 | # CONFIG_HUSH is not set | 1172 | # CONFIG_HUSH is not set |
1168 | # CONFIG_SHELL_HUSH is not set | 1173 | # CONFIG_SHELL_HUSH is not set |
diff --git a/shell/ash.c b/shell/ash.c index a24ed0ac8..63eb4947c 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -192,6 +192,14 @@ | |||
192 | //config: Enable support for the 'nocaseglob' option, which allows | 192 | //config: Enable support for the 'nocaseglob' option, which allows |
193 | //config: case-insensitive filename globbing. | 193 | //config: case-insensitive filename globbing. |
194 | //config: | 194 | //config: |
195 | //config:config ASH_IGNORE_CR | ||
196 | //config: bool "Ignore CR in scripts" | ||
197 | //config: default y | ||
198 | //config: depends on (ASH || SH_IS_ASH || BASH_IS_ASH) && PLATFORM_MINGW32 | ||
199 | //config: help | ||
200 | //config: Allow CRs to be ignored when shell scripts are parsed. This | ||
201 | //config: makes it possible to run scripts with CRLF line endings. | ||
202 | //config: | ||
195 | //config:endif # ash options | 203 | //config:endif # ash options |
196 | 204 | ||
197 | //applet:IF_ASH(APPLET(ash, BB_DIR_BIN, BB_SUID_DROP)) | 205 | //applet:IF_ASH(APPLET(ash, BB_DIR_BIN, BB_SUID_DROP)) |
@@ -762,7 +770,11 @@ struct strpush { | |||
762 | struct strpush *spfree; | 770 | struct strpush *spfree; |
763 | 771 | ||
764 | /* Remember last two characters for pungetc. */ | 772 | /* Remember last two characters for pungetc. */ |
773 | #if ENABLE_ASH_IGNORE_CR | ||
774 | int lastc[3]; /* Ignoring CRs needs more pungetc. */ | ||
775 | #else | ||
765 | int lastc[2]; | 776 | int lastc[2]; |
777 | #endif | ||
766 | 778 | ||
767 | /* Number of outstanding calls to pungetc. */ | 779 | /* Number of outstanding calls to pungetc. */ |
768 | int unget; | 780 | int unget; |
@@ -787,7 +799,11 @@ struct parsefile { | |||
787 | struct strpush *spfree; | 799 | struct strpush *spfree; |
788 | 800 | ||
789 | /* Remember last two characters for pungetc. */ | 801 | /* Remember last two characters for pungetc. */ |
802 | #if ENABLE_ASH_IGNORE_CR | ||
803 | int lastc[3]; /* Ignoring CRs needs more pungetc. */ | ||
804 | #else | ||
790 | int lastc[2]; | 805 | int lastc[2]; |
806 | #endif | ||
791 | 807 | ||
792 | /* Number of outstanding calls to pungetc. */ | 808 | /* Number of outstanding calls to pungetc. */ |
793 | int unget; | 809 | int unget; |
@@ -3596,7 +3612,11 @@ static const uint8_t syntax_index_table[] ALIGN1 = { | |||
3596 | /* 10 "\n" */ CNL_CNL_CNL_CNL, | 3612 | /* 10 "\n" */ CNL_CNL_CNL_CNL, |
3597 | /* 11 */ CWORD_CWORD_CWORD_CWORD, | 3613 | /* 11 */ CWORD_CWORD_CWORD_CWORD, |
3598 | /* 12 */ CWORD_CWORD_CWORD_CWORD, | 3614 | /* 12 */ CWORD_CWORD_CWORD_CWORD, |
3615 | #if ENABLE_ASH_IGNORE_CR | ||
3616 | /* 13 */ CSPCL_CWORD_CWORD_CWORD, | ||
3617 | #else | ||
3599 | /* 13 */ CWORD_CWORD_CWORD_CWORD, | 3618 | /* 13 */ CWORD_CWORD_CWORD_CWORD, |
3619 | #endif | ||
3600 | /* 14 */ CWORD_CWORD_CWORD_CWORD, | 3620 | /* 14 */ CWORD_CWORD_CWORD_CWORD, |
3601 | /* 15 */ CWORD_CWORD_CWORD_CWORD, | 3621 | /* 15 */ CWORD_CWORD_CWORD_CWORD, |
3602 | /* 16 */ CWORD_CWORD_CWORD_CWORD, | 3622 | /* 16 */ CWORD_CWORD_CWORD_CWORD, |
@@ -11846,7 +11866,9 @@ preadbuffer(void) | |||
11846 | more--; | 11866 | more--; |
11847 | 11867 | ||
11848 | c = *q; | 11868 | c = *q; |
11849 | if (c == '\0' || (ENABLE_PLATFORM_MINGW32 && c == '\r')) { | 11869 | /* Remove CR from input buffer as an alternative to ASH_IGNORE_CR. */ |
11870 | if (c == '\0' || (c == '\r' && | ||
11871 | ENABLE_PLATFORM_MINGW32 && !ENABLE_ASH_IGNORE_CR)) { | ||
11850 | memmove(q, q + 1, more); | 11872 | memmove(q, q + 1, more); |
11851 | } else { | 11873 | } else { |
11852 | q++; | 11874 | q++; |
@@ -11934,6 +11956,9 @@ static int __pgetc(void) | |||
11934 | else | 11956 | else |
11935 | c = preadbuffer(); | 11957 | c = preadbuffer(); |
11936 | 11958 | ||
11959 | #if ENABLE_ASH_IGNORE_CR | ||
11960 | g_parsefile->lastc[2] = g_parsefile->lastc[1]; | ||
11961 | #endif | ||
11937 | g_parsefile->lastc[1] = g_parsefile->lastc[0]; | 11962 | g_parsefile->lastc[1] = g_parsefile->lastc[0]; |
11938 | g_parsefile->lastc[0] = c; | 11963 | g_parsefile->lastc[0] = c; |
11939 | 11964 | ||
@@ -11971,11 +11996,24 @@ pgetc_eatbnl(void) | |||
11971 | int c; | 11996 | int c; |
11972 | 11997 | ||
11973 | while ((c = pgetc()) == '\\') { | 11998 | while ((c = pgetc()) == '\\') { |
11999 | #if !ENABLE_ASH_IGNORE_CR | ||
11974 | if (pgetc() != '\n') { | 12000 | if (pgetc() != '\n') { |
11975 | pungetc(); | 12001 | pungetc(); |
11976 | break; | 12002 | break; |
11977 | } | 12003 | } |
11978 | 12004 | #else | |
12005 | int c2 = pgetc(); | ||
12006 | if (c2 == '\r') { | ||
12007 | if (pgetc() == '\n') | ||
12008 | goto eatbnl; | ||
12009 | pungetc(); | ||
12010 | } | ||
12011 | if (c2 != '\n') { | ||
12012 | pungetc(); | ||
12013 | break; | ||
12014 | } | ||
12015 | eatbnl: | ||
12016 | #endif | ||
11979 | nlprompt(); | 12017 | nlprompt(); |
11980 | } | 12018 | } |
11981 | 12019 | ||
@@ -14114,7 +14152,7 @@ xxreadtoken(void) | |||
14114 | setprompt_if(needprompt, 2); | 14152 | setprompt_if(needprompt, 2); |
14115 | for (;;) { /* until token or start of word found */ | 14153 | for (;;) { /* until token or start of word found */ |
14116 | c = pgetc_eatbnl(); | 14154 | c = pgetc_eatbnl(); |
14117 | if (c == ' ' || c == '\t') | 14155 | if (c == ' ' || c == '\t' || (ENABLE_ASH_IGNORE_CR && c == '\r')) |
14118 | continue; | 14156 | continue; |
14119 | 14157 | ||
14120 | if (c == '#') { | 14158 | if (c == '#') { |