aboutsummaryrefslogtreecommitdiff
path: root/shell
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2023-02-07 10:03:04 +0000
committerRon Yorston <rmy@pobox.com>2023-02-07 10:03:04 +0000
commit4b894b60ae377ee2a04ae209c14bb1e714ecf6f4 (patch)
tree8f42f36eb0a9dad2c712f7b0e07aff7dee059217 /shell
parentc49b8b7052bb1df3ed5f9aeba61a7965d9c77f83 (diff)
downloadbusybox-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.c44
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 == '#') {