ash: fix $IFS handling in read. closes bug 235
This commit is contained in:
parent
7566bae197
commit
46aeab9a34
31
shell/ash.c
31
shell/ash.c
@ -12574,7 +12574,7 @@ readcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
|
||||
#endif
|
||||
|
||||
status = 0;
|
||||
startword = 1;
|
||||
startword = 2;
|
||||
backslash = 0;
|
||||
#if ENABLE_ASH_READ_TIMEOUT
|
||||
if (timeout) /* NB: ensuring end_ms is nonzero */
|
||||
@ -12582,6 +12582,8 @@ readcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
|
||||
#endif
|
||||
STARTSTACKSTR(p);
|
||||
do {
|
||||
const char *is_ifs;
|
||||
|
||||
#if ENABLE_ASH_READ_TIMEOUT
|
||||
if (end_ms) {
|
||||
struct pollfd pfd[1];
|
||||
@ -12611,26 +12613,35 @@ readcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
|
||||
continue;
|
||||
}
|
||||
if (!rflag && c == '\\') {
|
||||
backslash++;
|
||||
backslash = 1;
|
||||
continue;
|
||||
}
|
||||
if (c == '\n')
|
||||
break;
|
||||
if (startword && *ifs == ' ' && strchr(ifs, c)) {
|
||||
is_ifs = strchr(ifs, c);
|
||||
if (startword && is_ifs) {
|
||||
if (isspace(c))
|
||||
continue;
|
||||
/* non-space ifs char */
|
||||
startword--;
|
||||
if (startword == 1) /* first one? */
|
||||
continue;
|
||||
}
|
||||
startword = 0;
|
||||
if (ap[1] != NULL && strchr(ifs, c) != NULL) {
|
||||
if (ap[1] != NULL && is_ifs) {
|
||||
const char *beg;
|
||||
STACKSTRNUL(p);
|
||||
setvar(*ap, stackblock(), 0);
|
||||
beg = stackblock();
|
||||
setvar(*ap, beg, 0);
|
||||
ap++;
|
||||
startword = 1;
|
||||
/* can we skip one non-space ifs? (2: yes) */
|
||||
startword = isspace(c) ? 2 : 1;
|
||||
STARTSTACKSTR(p);
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
put:
|
||||
STPUTC(c, p);
|
||||
}
|
||||
}
|
||||
/* end of do {} while: */
|
||||
#if ENABLE_ASH_READ_NCHARS
|
||||
while (--nchars);
|
||||
@ -12643,8 +12654,8 @@ readcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
|
||||
#endif
|
||||
|
||||
STACKSTRNUL(p);
|
||||
/* Remove trailing blanks */
|
||||
while ((char *)stackblock() <= --p && strchr(ifs, *p) != NULL)
|
||||
/* Remove trailing space ifs chars */
|
||||
while ((char *)stackblock() <= --p && isspace(*p) && strchr(ifs, *p) != NULL)
|
||||
*p = '\0';
|
||||
setvar(*ap, stackblock(), 0);
|
||||
while (*++ap != NULL)
|
||||
|
7
shell/ash_test/ash-read/read_ifs.right
Normal file
7
shell/ash_test/ash-read/read_ifs.right
Normal file
@ -0,0 +1,7 @@
|
||||
.a. .b. .c.
|
||||
.a. .b. .c.
|
||||
.a. .. .b,c.
|
||||
.a. .. .b,c.
|
||||
.a. .. .c.
|
||||
.a. .. .c. .d.
|
||||
.a. .. .b,c,d , ,.
|
7
shell/ash_test/ash-read/read_ifs.tests
Executable file
7
shell/ash_test/ash-read/read_ifs.tests
Executable file
@ -0,0 +1,7 @@
|
||||
printf 'a\t\tb\tc\n' | ( IFS=$(printf "\t") read a b c; echo ".$a. .$b. .$c." )
|
||||
printf 'a\t\tb\tc\n' | ( IFS=$(printf " \t") read a b c; echo ".$a. .$b. .$c." )
|
||||
printf 'a,,b,c\n' | ( IFS="," read a b c; echo ".$a. .$b. .$c." )
|
||||
printf 'a,,b,c\n' | ( IFS=" ," read a b c; echo ".$a. .$b. .$c." )
|
||||
printf 'a ,, c\n' | ( IFS=" ," read a b c; echo ".$a. .$b. .$c." )
|
||||
printf 'a ,, c d\n' | ( IFS=" ," read a b c d; echo ".$a. .$b. .$c. .$d." )
|
||||
printf ' a,,b,c,d , ,\n' | ( IFS=" ," read a b c; echo ".$a. .$b. .$c." )
|
Loading…
Reference in New Issue
Block a user