diff options
-rw-r--r-- | shell/ash.c | 14 | ||||
-rw-r--r-- | shell/ash_test/ash-vars/var_wordsplit_ifs1.right | 25 | ||||
-rwxr-xr-x | shell/ash_test/ash-vars/var_wordsplit_ifs1.tests | 21 | ||||
-rw-r--r-- | shell/hush_test/hush-vars/var_wordsplit_ifs1.right | 25 | ||||
-rwxr-xr-x | shell/hush_test/hush-vars/var_wordsplit_ifs1.tests | 21 |
5 files changed, 101 insertions, 5 deletions
diff --git a/shell/ash.c b/shell/ash.c index e4349ccad..56dbcb7d1 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -6606,7 +6606,7 @@ subevalvar(char *p, char *varname, int strloc, int subtype, | |||
6606 | * ash -c 'echo ${#1#}' name:'1=#' | 6606 | * ash -c 'echo ${#1#}' name:'1=#' |
6607 | */ | 6607 | */ |
6608 | static NOINLINE ssize_t | 6608 | static NOINLINE ssize_t |
6609 | varvalue(char *name, int varflags, int flags, struct strlist *var_str_list) | 6609 | varvalue(char *name, int varflags, int flags, struct strlist *var_str_list, int *nulonly) |
6610 | { | 6610 | { |
6611 | const char *p; | 6611 | const char *p; |
6612 | int num; | 6612 | int num; |
@@ -6619,7 +6619,8 @@ varvalue(char *name, int varflags, int flags, struct strlist *var_str_list) | |||
6619 | int quotes = (discard ? 0 : (flags & QUOTES_ESC)) | QUOTES_KEEPNUL; | 6619 | int quotes = (discard ? 0 : (flags & QUOTES_ESC)) | QUOTES_KEEPNUL; |
6620 | int syntax = quoted ? DQSYNTAX : BASESYNTAX; | 6620 | int syntax = quoted ? DQSYNTAX : BASESYNTAX; |
6621 | 6621 | ||
6622 | sep = quoted ? ((flags & EXP_FULL) << CHAR_BIT) : 0; | 6622 | sep = *nulonly ? (flags & EXP_FULL) << CHAR_BIT : 0; |
6623 | *nulonly = 0; | ||
6623 | 6624 | ||
6624 | switch (*name) { | 6625 | switch (*name) { |
6625 | case '$': | 6626 | case '$': |
@@ -6664,10 +6665,11 @@ varvalue(char *name, int varflags, int flags, struct strlist *var_str_list) | |||
6664 | } | 6665 | } |
6665 | /* fall through */ | 6666 | /* fall through */ |
6666 | case '*': | 6667 | case '*': |
6667 | sep = ifsset() ? (unsigned char)(ifsval()[0]) : ' '; | 6668 | sep |= ifsset() ? (unsigned char)(ifsval()[0]) : ' '; |
6668 | param: | 6669 | param: |
6669 | ap = shellparam.p; | 6670 | ap = shellparam.p; |
6670 | sepc = sep; | 6671 | sepc = sep; |
6672 | *nulonly = !sepc; | ||
6671 | if (!ap) | 6673 | if (!ap) |
6672 | return -1; | 6674 | return -1; |
6673 | while ((p = *ap++) != NULL) { | 6675 | while ((p = *ap++) != NULL) { |
@@ -6757,6 +6759,7 @@ evalvar(char *p, int flags, struct strlist *var_str_list) | |||
6757 | char subtype; | 6759 | char subtype; |
6758 | int quoted; | 6760 | int quoted; |
6759 | char easy; | 6761 | char easy; |
6762 | int nulonly; | ||
6760 | char *var; | 6763 | char *var; |
6761 | int patloc; | 6764 | int patloc; |
6762 | int startloc; | 6765 | int startloc; |
@@ -6767,11 +6770,12 @@ evalvar(char *p, int flags, struct strlist *var_str_list) | |||
6767 | quoted = flags & EXP_QUOTED; | 6770 | quoted = flags & EXP_QUOTED; |
6768 | var = p; | 6771 | var = p; |
6769 | easy = (!quoted || (*var == '@' && shellparam.nparam)); | 6772 | easy = (!quoted || (*var == '@' && shellparam.nparam)); |
6773 | nulonly = easy; | ||
6770 | startloc = expdest - (char *)stackblock(); | 6774 | startloc = expdest - (char *)stackblock(); |
6771 | p = strchr(p, '=') + 1; //TODO: use var_end(p)? | 6775 | p = strchr(p, '=') + 1; //TODO: use var_end(p)? |
6772 | 6776 | ||
6773 | again: | 6777 | again: |
6774 | varlen = varvalue(var, varflags, flags, var_str_list); | 6778 | varlen = varvalue(var, varflags, flags, var_str_list, &nulonly); |
6775 | if (varflags & VSNUL) | 6779 | if (varflags & VSNUL) |
6776 | varlen--; | 6780 | varlen--; |
6777 | 6781 | ||
@@ -6865,7 +6869,7 @@ evalvar(char *p, int flags, struct strlist *var_str_list) | |||
6865 | /* Remove any recorded regions beyond start of variable */ | 6869 | /* Remove any recorded regions beyond start of variable */ |
6866 | removerecordregions(startloc); | 6870 | removerecordregions(startloc); |
6867 | record: | 6871 | record: |
6868 | recordregion(startloc, expdest - (char *)stackblock(), quoted); | 6872 | recordregion(startloc, expdest - (char *)stackblock(), nulonly); |
6869 | } | 6873 | } |
6870 | 6874 | ||
6871 | end: | 6875 | end: |
diff --git a/shell/ash_test/ash-vars/var_wordsplit_ifs1.right b/shell/ash_test/ash-vars/var_wordsplit_ifs1.right new file mode 100644 index 000000000..efdafc70f --- /dev/null +++ b/shell/ash_test/ash-vars/var_wordsplit_ifs1.right | |||
@@ -0,0 +1,25 @@ | |||
1 | Testing: !IFS $* | ||
2 | .abc. | ||
3 | .d. | ||
4 | .e. | ||
5 | Testing: !IFS $@ | ||
6 | .abc. | ||
7 | .d. | ||
8 | .e. | ||
9 | Testing: !IFS "$*" | ||
10 | .abc d e. | ||
11 | Testing: !IFS "$@" | ||
12 | .abc. | ||
13 | .d e. | ||
14 | Testing: IFS="" $* | ||
15 | .abc. | ||
16 | .d e. | ||
17 | Testing: IFS="" $@ | ||
18 | .abc. | ||
19 | .d e. | ||
20 | Testing: IFS="" "$*" | ||
21 | .abcd e. | ||
22 | Testing: IFS="" "$@" | ||
23 | .abc. | ||
24 | .d e. | ||
25 | Finished | ||
diff --git a/shell/ash_test/ash-vars/var_wordsplit_ifs1.tests b/shell/ash_test/ash-vars/var_wordsplit_ifs1.tests new file mode 100755 index 000000000..532ab992e --- /dev/null +++ b/shell/ash_test/ash-vars/var_wordsplit_ifs1.tests | |||
@@ -0,0 +1,21 @@ | |||
1 | set -- abc "d e" | ||
2 | |||
3 | echo 'Testing: !IFS $*' | ||
4 | unset IFS; for a in $*; do echo ".$a."; done | ||
5 | echo 'Testing: !IFS $@' | ||
6 | unset IFS; for a in $@; do echo ".$a."; done | ||
7 | echo 'Testing: !IFS "$*"' | ||
8 | unset IFS; for a in "$*"; do echo ".$a."; done | ||
9 | echo 'Testing: !IFS "$@"' | ||
10 | unset IFS; for a in "$@"; do echo ".$a."; done | ||
11 | |||
12 | echo 'Testing: IFS="" $*' | ||
13 | IFS=""; for a in $*; do echo ".$a."; done | ||
14 | echo 'Testing: IFS="" $@' | ||
15 | IFS=""; for a in $@; do echo ".$a."; done | ||
16 | echo 'Testing: IFS="" "$*"' | ||
17 | IFS=""; for a in "$*"; do echo ".$a."; done | ||
18 | echo 'Testing: IFS="" "$@"' | ||
19 | IFS=""; for a in "$@"; do echo ".$a."; done | ||
20 | |||
21 | echo Finished | ||
diff --git a/shell/hush_test/hush-vars/var_wordsplit_ifs1.right b/shell/hush_test/hush-vars/var_wordsplit_ifs1.right new file mode 100644 index 000000000..efdafc70f --- /dev/null +++ b/shell/hush_test/hush-vars/var_wordsplit_ifs1.right | |||
@@ -0,0 +1,25 @@ | |||
1 | Testing: !IFS $* | ||
2 | .abc. | ||
3 | .d. | ||
4 | .e. | ||
5 | Testing: !IFS $@ | ||
6 | .abc. | ||
7 | .d. | ||
8 | .e. | ||
9 | Testing: !IFS "$*" | ||
10 | .abc d e. | ||
11 | Testing: !IFS "$@" | ||
12 | .abc. | ||
13 | .d e. | ||
14 | Testing: IFS="" $* | ||
15 | .abc. | ||
16 | .d e. | ||
17 | Testing: IFS="" $@ | ||
18 | .abc. | ||
19 | .d e. | ||
20 | Testing: IFS="" "$*" | ||
21 | .abcd e. | ||
22 | Testing: IFS="" "$@" | ||
23 | .abc. | ||
24 | .d e. | ||
25 | Finished | ||
diff --git a/shell/hush_test/hush-vars/var_wordsplit_ifs1.tests b/shell/hush_test/hush-vars/var_wordsplit_ifs1.tests new file mode 100755 index 000000000..532ab992e --- /dev/null +++ b/shell/hush_test/hush-vars/var_wordsplit_ifs1.tests | |||
@@ -0,0 +1,21 @@ | |||
1 | set -- abc "d e" | ||
2 | |||
3 | echo 'Testing: !IFS $*' | ||
4 | unset IFS; for a in $*; do echo ".$a."; done | ||
5 | echo 'Testing: !IFS $@' | ||
6 | unset IFS; for a in $@; do echo ".$a."; done | ||
7 | echo 'Testing: !IFS "$*"' | ||
8 | unset IFS; for a in "$*"; do echo ".$a."; done | ||
9 | echo 'Testing: !IFS "$@"' | ||
10 | unset IFS; for a in "$@"; do echo ".$a."; done | ||
11 | |||
12 | echo 'Testing: IFS="" $*' | ||
13 | IFS=""; for a in $*; do echo ".$a."; done | ||
14 | echo 'Testing: IFS="" $@' | ||
15 | IFS=""; for a in $@; do echo ".$a."; done | ||
16 | echo 'Testing: IFS="" "$*"' | ||
17 | IFS=""; for a in "$*"; do echo ".$a."; done | ||
18 | echo 'Testing: IFS="" "$@"' | ||
19 | IFS=""; for a in "$@"; do echo ".$a."; done | ||
20 | |||
21 | echo Finished | ||