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 /shell | |
| 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)
Diffstat (limited to 'shell')
| -rw-r--r-- | shell/ash.c | 44 |
1 files changed, 41 insertions, 3 deletions
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 == '#') { |
