aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2009-03-31 19:18:17 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2009-03-31 19:18:17 +0000
commit46aeab9a349d097307a87d7dfde3057f9e4e6722 (patch)
treed348fadeb6bc0766c21bfc850a174a059fe4c732
parent7566bae19715a493f40fd3fae4d69d10089af411 (diff)
downloadbusybox-w32-46aeab9a349d097307a87d7dfde3057f9e4e6722.tar.gz
busybox-w32-46aeab9a349d097307a87d7dfde3057f9e4e6722.tar.bz2
busybox-w32-46aeab9a349d097307a87d7dfde3057f9e4e6722.zip
ash: fix $IFS handling in read. closes bug 235
-rw-r--r--shell/ash.c35
-rw-r--r--shell/ash_test/ash-read/read_ifs.right7
-rwxr-xr-xshell/ash_test/ash-read/read_ifs.tests7
3 files changed, 37 insertions, 12 deletions
diff --git a/shell/ash.c b/shell/ash.c
index 13b4329b5..1de989ef3 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -12574,7 +12574,7 @@ readcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
12574#endif 12574#endif
12575 12575
12576 status = 0; 12576 status = 0;
12577 startword = 1; 12577 startword = 2;
12578 backslash = 0; 12578 backslash = 0;
12579#if ENABLE_ASH_READ_TIMEOUT 12579#if ENABLE_ASH_READ_TIMEOUT
12580 if (timeout) /* NB: ensuring end_ms is nonzero */ 12580 if (timeout) /* NB: ensuring end_ms is nonzero */
@@ -12582,6 +12582,8 @@ readcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
12582#endif 12582#endif
12583 STARTSTACKSTR(p); 12583 STARTSTACKSTR(p);
12584 do { 12584 do {
12585 const char *is_ifs;
12586
12585#if ENABLE_ASH_READ_TIMEOUT 12587#if ENABLE_ASH_READ_TIMEOUT
12586 if (end_ms) { 12588 if (end_ms) {
12587 struct pollfd pfd[1]; 12589 struct pollfd pfd[1];
@@ -12611,25 +12613,34 @@ readcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
12611 continue; 12613 continue;
12612 } 12614 }
12613 if (!rflag && c == '\\') { 12615 if (!rflag && c == '\\') {
12614 backslash++; 12616 backslash = 1;
12615 continue; 12617 continue;
12616 } 12618 }
12617 if (c == '\n') 12619 if (c == '\n')
12618 break; 12620 break;
12619 if (startword && *ifs == ' ' && strchr(ifs, c)) { 12621 is_ifs = strchr(ifs, c);
12620 continue; 12622 if (startword && is_ifs) {
12623 if (isspace(c))
12624 continue;
12625 /* non-space ifs char */
12626 startword--;
12627 if (startword == 1) /* first one? */
12628 continue;
12621 } 12629 }
12622 startword = 0; 12630 startword = 0;
12623 if (ap[1] != NULL && strchr(ifs, c) != NULL) { 12631 if (ap[1] != NULL && is_ifs) {
12632 const char *beg;
12624 STACKSTRNUL(p); 12633 STACKSTRNUL(p);
12625 setvar(*ap, stackblock(), 0); 12634 beg = stackblock();
12635 setvar(*ap, beg, 0);
12626 ap++; 12636 ap++;
12627 startword = 1; 12637 /* can we skip one non-space ifs? (2: yes) */
12638 startword = isspace(c) ? 2 : 1;
12628 STARTSTACKSTR(p); 12639 STARTSTACKSTR(p);
12629 } else { 12640 continue;
12630 put:
12631 STPUTC(c, p);
12632 } 12641 }
12642 put:
12643 STPUTC(c, p);
12633 } 12644 }
12634/* end of do {} while: */ 12645/* end of do {} while: */
12635#if ENABLE_ASH_READ_NCHARS 12646#if ENABLE_ASH_READ_NCHARS
@@ -12643,8 +12654,8 @@ readcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
12643#endif 12654#endif
12644 12655
12645 STACKSTRNUL(p); 12656 STACKSTRNUL(p);
12646 /* Remove trailing blanks */ 12657 /* Remove trailing space ifs chars */
12647 while ((char *)stackblock() <= --p && strchr(ifs, *p) != NULL) 12658 while ((char *)stackblock() <= --p && isspace(*p) && strchr(ifs, *p) != NULL)
12648 *p = '\0'; 12659 *p = '\0';
12649 setvar(*ap, stackblock(), 0); 12660 setvar(*ap, stackblock(), 0);
12650 while (*++ap != NULL) 12661 while (*++ap != NULL)
diff --git a/shell/ash_test/ash-read/read_ifs.right b/shell/ash_test/ash-read/read_ifs.right
new file mode 100644
index 000000000..027ecd18f
--- /dev/null
+++ b/shell/ash_test/ash-read/read_ifs.right
@@ -0,0 +1,7 @@
1.a. .b. .c.
2.a. .b. .c.
3.a. .. .b,c.
4.a. .. .b,c.
5.a. .. .c.
6.a. .. .c. .d.
7.a. .. .b,c,d , ,.
diff --git a/shell/ash_test/ash-read/read_ifs.tests b/shell/ash_test/ash-read/read_ifs.tests
new file mode 100755
index 000000000..cf7cd934c
--- /dev/null
+++ b/shell/ash_test/ash-read/read_ifs.tests
@@ -0,0 +1,7 @@
1printf 'a\t\tb\tc\n' | ( IFS=$(printf "\t") read a b c; echo ".$a. .$b. .$c." )
2printf 'a\t\tb\tc\n' | ( IFS=$(printf " \t") read a b c; echo ".$a. .$b. .$c." )
3printf 'a,,b,c\n' | ( IFS="," read a b c; echo ".$a. .$b. .$c." )
4printf 'a,,b,c\n' | ( IFS=" ," read a b c; echo ".$a. .$b. .$c." )
5printf 'a ,, c\n' | ( IFS=" ," read a b c; echo ".$a. .$b. .$c." )
6printf 'a ,, c d\n' | ( IFS=" ," read a b c d; echo ".$a. .$b. .$c. .$d." )
7printf ' a,,b,c,d , ,\n' | ( IFS=" ," read a b c; echo ".$a. .$b. .$c." )