From 4b894b60ae377ee2a04ae209c14bb1e714ecf6f4 Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Tue, 7 Feb 2023 10:03:04 +0000 Subject: 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) --- configs/mingw32_defconfig | 9 +++++++-- configs/mingw64_defconfig | 9 +++++++-- 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 @@ # # Automatically generated make config: don't edit -# Busybox version: 1.36.0.git -# Wed Oct 12 10:45:30 2022 +# Busybox version: 1.37.0.git +# Tue Feb 7 09:34:52 2023 # CONFIG_HAVE_DOT_CONFIG=y # CONFIG_PLATFORM_POSIX is not set @@ -145,6 +145,9 @@ CONFIG_LAST_SUPPORTED_WCHAR=0 # CONFIG_UNICODE_BIDI_SUPPORT is not set # CONFIG_UNICODE_NEUTRAL_TABLE is not set # CONFIG_UNICODE_PRESERVE_BROKEN is not set +# CONFIG_LOOP_CONFIGURE is not set +# CONFIG_NO_LOOP_CONFIGURE is not set +CONFIG_TRY_LOOP_CONFIGURE=y # # Applets @@ -1027,6 +1030,7 @@ CONFIG_DHCPD_LEASES_FILE="" # CONFIG_FEATURE_UDHCPC_ARPING is not set # CONFIG_FEATURE_UDHCPC_SANITIZEOPT is not set CONFIG_UDHCPC_DEFAULT_SCRIPT="" +CONFIG_UDHCPC6_DEFAULT_SCRIPT="" # CONFIG_UDHCPC6 is not set # CONFIG_FEATURE_UDHCPC6_RFC3646 is not set # CONFIG_FEATURE_UDHCPC6_RFC4704 is not set @@ -1163,6 +1167,7 @@ CONFIG_ASH_GETOPTS=y CONFIG_ASH_CMDCMD=y CONFIG_ASH_NOCONSOLE=y CONFIG_ASH_NOCASEGLOB=y +CONFIG_ASH_IGNORE_CR=y # CONFIG_CTTYHACK is not set # CONFIG_HUSH is not set # 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 @@ # # Automatically generated make config: don't edit -# Busybox version: 1.36.0.git -# Wed Oct 12 10:45:30 2022 +# Busybox version: 1.37.0.git +# Tue Feb 7 09:34:52 2023 # CONFIG_HAVE_DOT_CONFIG=y # CONFIG_PLATFORM_POSIX is not set @@ -145,6 +145,9 @@ CONFIG_LAST_SUPPORTED_WCHAR=0 # CONFIG_UNICODE_BIDI_SUPPORT is not set # CONFIG_UNICODE_NEUTRAL_TABLE is not set # CONFIG_UNICODE_PRESERVE_BROKEN is not set +# CONFIG_LOOP_CONFIGURE is not set +# CONFIG_NO_LOOP_CONFIGURE is not set +CONFIG_TRY_LOOP_CONFIGURE=y # # Applets @@ -1027,6 +1030,7 @@ CONFIG_DHCPD_LEASES_FILE="" # CONFIG_FEATURE_UDHCPC_ARPING is not set # CONFIG_FEATURE_UDHCPC_SANITIZEOPT is not set CONFIG_UDHCPC_DEFAULT_SCRIPT="" +CONFIG_UDHCPC6_DEFAULT_SCRIPT="" # CONFIG_UDHCPC6 is not set # CONFIG_FEATURE_UDHCPC6_RFC3646 is not set # CONFIG_FEATURE_UDHCPC6_RFC4704 is not set @@ -1163,6 +1167,7 @@ CONFIG_ASH_GETOPTS=y CONFIG_ASH_CMDCMD=y CONFIG_ASH_NOCONSOLE=y CONFIG_ASH_NOCASEGLOB=y +CONFIG_ASH_IGNORE_CR=y # CONFIG_CTTYHACK is not set # CONFIG_HUSH is not set # 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 @@ //config: Enable support for the 'nocaseglob' option, which allows //config: case-insensitive filename globbing. //config: +//config:config ASH_IGNORE_CR +//config: bool "Ignore CR in scripts" +//config: default y +//config: depends on (ASH || SH_IS_ASH || BASH_IS_ASH) && PLATFORM_MINGW32 +//config: help +//config: Allow CRs to be ignored when shell scripts are parsed. This +//config: makes it possible to run scripts with CRLF line endings. +//config: //config:endif # ash options //applet:IF_ASH(APPLET(ash, BB_DIR_BIN, BB_SUID_DROP)) @@ -762,7 +770,11 @@ struct strpush { struct strpush *spfree; /* Remember last two characters for pungetc. */ +#if ENABLE_ASH_IGNORE_CR + int lastc[3]; /* Ignoring CRs needs more pungetc. */ +#else int lastc[2]; +#endif /* Number of outstanding calls to pungetc. */ int unget; @@ -787,7 +799,11 @@ struct parsefile { struct strpush *spfree; /* Remember last two characters for pungetc. */ +#if ENABLE_ASH_IGNORE_CR + int lastc[3]; /* Ignoring CRs needs more pungetc. */ +#else int lastc[2]; +#endif /* Number of outstanding calls to pungetc. */ int unget; @@ -3596,7 +3612,11 @@ static const uint8_t syntax_index_table[] ALIGN1 = { /* 10 "\n" */ CNL_CNL_CNL_CNL, /* 11 */ CWORD_CWORD_CWORD_CWORD, /* 12 */ CWORD_CWORD_CWORD_CWORD, +#if ENABLE_ASH_IGNORE_CR + /* 13 */ CSPCL_CWORD_CWORD_CWORD, +#else /* 13 */ CWORD_CWORD_CWORD_CWORD, +#endif /* 14 */ CWORD_CWORD_CWORD_CWORD, /* 15 */ CWORD_CWORD_CWORD_CWORD, /* 16 */ CWORD_CWORD_CWORD_CWORD, @@ -11846,7 +11866,9 @@ preadbuffer(void) more--; c = *q; - if (c == '\0' || (ENABLE_PLATFORM_MINGW32 && c == '\r')) { + /* Remove CR from input buffer as an alternative to ASH_IGNORE_CR. */ + if (c == '\0' || (c == '\r' && + ENABLE_PLATFORM_MINGW32 && !ENABLE_ASH_IGNORE_CR)) { memmove(q, q + 1, more); } else { q++; @@ -11934,6 +11956,9 @@ static int __pgetc(void) else c = preadbuffer(); +#if ENABLE_ASH_IGNORE_CR + g_parsefile->lastc[2] = g_parsefile->lastc[1]; +#endif g_parsefile->lastc[1] = g_parsefile->lastc[0]; g_parsefile->lastc[0] = c; @@ -11971,11 +11996,24 @@ pgetc_eatbnl(void) int c; while ((c = pgetc()) == '\\') { +#if !ENABLE_ASH_IGNORE_CR if (pgetc() != '\n') { pungetc(); break; } - +#else + int c2 = pgetc(); + if (c2 == '\r') { + if (pgetc() == '\n') + goto eatbnl; + pungetc(); + } + if (c2 != '\n') { + pungetc(); + break; + } + eatbnl: +#endif nlprompt(); } @@ -14114,7 +14152,7 @@ xxreadtoken(void) setprompt_if(needprompt, 2); for (;;) { /* until token or start of word found */ c = pgetc_eatbnl(); - if (c == ' ' || c == '\t') + if (c == ' ' || c == '\t' || (ENABLE_ASH_IGNORE_CR && c == '\r')) continue; if (c == '#') { -- cgit v1.2.3-55-g6feb