diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2016-10-02 02:46:56 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2016-10-02 02:46:56 +0200 |
commit | 0aaaa50b4551ab5912ccd95d66d633844eac6d85 (patch) | |
tree | 1a1f9e34c690051a678fb048064e4e98cca3536b /shell | |
parent | 42eeb255c1c5f35373d3e7bfa892e4f864cf1266 (diff) | |
download | busybox-w32-0aaaa50b4551ab5912ccd95d66d633844eac6d85.tar.gz busybox-w32-0aaaa50b4551ab5912ccd95d66d633844eac6d85.tar.bz2 busybox-w32-0aaaa50b4551ab5912ccd95d66d633844eac6d85.zip |
ash: expand: Fixed "$@" expansion when EXP_FULL is false
Upstream commit:
Date: Thu, 1 Jan 2015 07:53:10 +1100
expand: Fixed "$@" expansion when EXP_FULL is false
The commit 3c06acdac0b1ba0e0acdda513a57ee6e31385dce ([EXPAND]
Split unquoted $@/$* correctly when IFS is set but empty) broke
the case where $@ is in quotes and EXP_FULL is false.
In that case we should still emit IFS as field splitting is not
performed.
Reported-by: Juergen Daubert <jue@jue.li>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'shell')
-rw-r--r-- | shell/ash.c | 28 | ||||
-rw-r--r-- | shell/ash_test/ash-vars/var_wordsplit_ifs1.right | 16 | ||||
-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 | 16 | ||||
-rwxr-xr-x | shell/hush_test/hush-vars/var_wordsplit_ifs1.tests | 21 |
5 files changed, 87 insertions, 15 deletions
diff --git a/shell/ash.c b/shell/ash.c index 731c4b2b0..4f6ba0c70 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -6615,7 +6615,10 @@ varvalue(char *name, int varflags, int flags, struct strlist *var_str_list, int | |||
6615 | int subtype = varflags & VSTYPE; | 6615 | int subtype = varflags & VSTYPE; |
6616 | int discard = subtype == VSPLUS || subtype == VSLENGTH; | 6616 | int discard = subtype == VSPLUS || subtype == VSLENGTH; |
6617 | int quotes = (discard ? 0 : (flags & QUOTES_ESC)) | QUOTES_KEEPNUL; | 6617 | int quotes = (discard ? 0 : (flags & QUOTES_ESC)) | QUOTES_KEEPNUL; |
6618 | int syntax = quoted ? DQSYNTAX : BASESYNTAX; | 6618 | int syntax; |
6619 | |||
6620 | sep = (flags & EXP_FULL) << CHAR_BIT; | ||
6621 | syntax = quoted ? DQSYNTAX : BASESYNTAX; | ||
6619 | 6622 | ||
6620 | switch (*name) { | 6623 | switch (*name) { |
6621 | case '$': | 6624 | case '$': |
@@ -6649,23 +6652,18 @@ varvalue(char *name, int varflags, int flags, struct strlist *var_str_list, int | |||
6649 | raise_error_syntax("bad substitution"); | 6652 | raise_error_syntax("bad substitution"); |
6650 | #endif | 6653 | #endif |
6651 | break; | 6654 | break; |
6652 | case '@': { | 6655 | case '@': |
6656 | if (quoted && sep) | ||
6657 | goto param; | ||
6658 | /* fall through */ | ||
6659 | case '*': { | ||
6653 | char **ap; | 6660 | char **ap; |
6654 | char sepc; | 6661 | char sepc; |
6655 | 6662 | ||
6656 | sep = 0; | 6663 | if (quoted) |
6657 | if (quoted && (flags & EXP_FULL)) { | 6664 | sep = 0; |
6658 | /* note: this is not meant as PEOF value */ | 6665 | sep |= ifsset() ? ifsval()[0] : ' '; |
6659 | sep = 1 << CHAR_BIT; | ||
6660 | goto param; | ||
6661 | } | ||
6662 | /* fall through */ | ||
6663 | case '*': | ||
6664 | sep = ifsset() ? (unsigned char)(ifsval()[0]) : ' '; | ||
6665 | if (!quoted) { | ||
6666 | param: | 6666 | param: |
6667 | sep |= (flags & EXP_FULL) << CHAR_BIT; | ||
6668 | } | ||
6669 | sepc = sep; | 6667 | sepc = sep; |
6670 | *quotedp = !sepc; | 6668 | *quotedp = !sepc; |
6671 | ap = shellparam.p; | 6669 | ap = shellparam.p; |
@@ -6680,7 +6678,7 @@ varvalue(char *name, int varflags, int flags, struct strlist *var_str_list, int | |||
6680 | } | 6678 | } |
6681 | } | 6679 | } |
6682 | break; | 6680 | break; |
6683 | } /* case '@' and '*' */ | 6681 | } /* case '*' */ |
6684 | case '0': | 6682 | case '0': |
6685 | case '1': | 6683 | case '1': |
6686 | case '2': | 6684 | case '2': |
diff --git a/shell/ash_test/ash-vars/var_wordsplit_ifs1.right b/shell/ash_test/ash-vars/var_wordsplit_ifs1.right index efdafc70f..cf583d0aa 100644 --- a/shell/ash_test/ash-vars/var_wordsplit_ifs1.right +++ b/shell/ash_test/ash-vars/var_wordsplit_ifs1.right | |||
@@ -22,4 +22,20 @@ Testing: IFS="" "$*" | |||
22 | Testing: IFS="" "$@" | 22 | Testing: IFS="" "$@" |
23 | .abc. | 23 | .abc. |
24 | .d e. | 24 | .d e. |
25 | Testing: !IFS v=$* | ||
26 | v='abc d e' | ||
27 | Testing: !IFS v=$@ | ||
28 | v='abc d e' | ||
29 | Testing: !IFS v="$*" | ||
30 | v='abc d e' | ||
31 | Testing: !IFS v="$@" | ||
32 | v='abc d e' | ||
33 | Testing: IFS="" v=$* | ||
34 | v='abcd e' | ||
35 | Testing: IFS="" v=$@ | ||
36 | v='abcd e' | ||
37 | Testing: IFS="" v="$*" | ||
38 | v='abcd e' | ||
39 | Testing: IFS="" v="$@" | ||
40 | v='abcd e' | ||
25 | Finished | 41 | Finished |
diff --git a/shell/ash_test/ash-vars/var_wordsplit_ifs1.tests b/shell/ash_test/ash-vars/var_wordsplit_ifs1.tests index 532ab992e..a62afc6fd 100755 --- a/shell/ash_test/ash-vars/var_wordsplit_ifs1.tests +++ b/shell/ash_test/ash-vars/var_wordsplit_ifs1.tests | |||
@@ -18,4 +18,25 @@ IFS=""; for a in "$*"; do echo ".$a."; done | |||
18 | echo 'Testing: IFS="" "$@"' | 18 | echo 'Testing: IFS="" "$@"' |
19 | IFS=""; for a in "$@"; do echo ".$a."; done | 19 | IFS=""; for a in "$@"; do echo ".$a."; done |
20 | 20 | ||
21 | echo 'Testing: !IFS v=$*' | ||
22 | unset IFS; v=$*; echo "v='$v'" | ||
23 | echo 'Testing: !IFS v=$@' | ||
24 | unset IFS; v=$@; echo "v='$v'" | ||
25 | echo 'Testing: !IFS v="$*"' | ||
26 | unset IFS; v="$*"; echo "v='$v'" | ||
27 | echo 'Testing: !IFS v="$@"' | ||
28 | unset IFS; v="$@"; echo "v='$v'" | ||
29 | |||
30 | echo 'Testing: IFS="" v=$*' | ||
31 | IFS=""; v=$*; echo "v='$v'" | ||
32 | echo 'Testing: IFS="" v=$@' | ||
33 | IFS=""; v=$@; echo "v='$v'" | ||
34 | echo 'Testing: IFS="" v="$*"' | ||
35 | IFS=""; v="$*"; echo "v='$v'" | ||
36 | echo 'Testing: IFS="" v="$@"' | ||
37 | IFS=""; v="$@"; echo "v='$v'" | ||
38 | |||
39 | # Note: in IFS="" v=$@ and IFS="" v="$@" cases, bash produces "abc d e" | ||
40 | # We produce "abcd e" | ||
41 | |||
21 | echo Finished | 42 | echo Finished |
diff --git a/shell/hush_test/hush-vars/var_wordsplit_ifs1.right b/shell/hush_test/hush-vars/var_wordsplit_ifs1.right index efdafc70f..cf583d0aa 100644 --- a/shell/hush_test/hush-vars/var_wordsplit_ifs1.right +++ b/shell/hush_test/hush-vars/var_wordsplit_ifs1.right | |||
@@ -22,4 +22,20 @@ Testing: IFS="" "$*" | |||
22 | Testing: IFS="" "$@" | 22 | Testing: IFS="" "$@" |
23 | .abc. | 23 | .abc. |
24 | .d e. | 24 | .d e. |
25 | Testing: !IFS v=$* | ||
26 | v='abc d e' | ||
27 | Testing: !IFS v=$@ | ||
28 | v='abc d e' | ||
29 | Testing: !IFS v="$*" | ||
30 | v='abc d e' | ||
31 | Testing: !IFS v="$@" | ||
32 | v='abc d e' | ||
33 | Testing: IFS="" v=$* | ||
34 | v='abcd e' | ||
35 | Testing: IFS="" v=$@ | ||
36 | v='abcd e' | ||
37 | Testing: IFS="" v="$*" | ||
38 | v='abcd e' | ||
39 | Testing: IFS="" v="$@" | ||
40 | v='abcd e' | ||
25 | Finished | 41 | Finished |
diff --git a/shell/hush_test/hush-vars/var_wordsplit_ifs1.tests b/shell/hush_test/hush-vars/var_wordsplit_ifs1.tests index 532ab992e..a62afc6fd 100755 --- a/shell/hush_test/hush-vars/var_wordsplit_ifs1.tests +++ b/shell/hush_test/hush-vars/var_wordsplit_ifs1.tests | |||
@@ -18,4 +18,25 @@ IFS=""; for a in "$*"; do echo ".$a."; done | |||
18 | echo 'Testing: IFS="" "$@"' | 18 | echo 'Testing: IFS="" "$@"' |
19 | IFS=""; for a in "$@"; do echo ".$a."; done | 19 | IFS=""; for a in "$@"; do echo ".$a."; done |
20 | 20 | ||
21 | echo 'Testing: !IFS v=$*' | ||
22 | unset IFS; v=$*; echo "v='$v'" | ||
23 | echo 'Testing: !IFS v=$@' | ||
24 | unset IFS; v=$@; echo "v='$v'" | ||
25 | echo 'Testing: !IFS v="$*"' | ||
26 | unset IFS; v="$*"; echo "v='$v'" | ||
27 | echo 'Testing: !IFS v="$@"' | ||
28 | unset IFS; v="$@"; echo "v='$v'" | ||
29 | |||
30 | echo 'Testing: IFS="" v=$*' | ||
31 | IFS=""; v=$*; echo "v='$v'" | ||
32 | echo 'Testing: IFS="" v=$@' | ||
33 | IFS=""; v=$@; echo "v='$v'" | ||
34 | echo 'Testing: IFS="" v="$*"' | ||
35 | IFS=""; v="$*"; echo "v='$v'" | ||
36 | echo 'Testing: IFS="" v="$@"' | ||
37 | IFS=""; v="$@"; echo "v='$v'" | ||
38 | |||
39 | # Note: in IFS="" v=$@ and IFS="" v="$@" cases, bash produces "abc d e" | ||
40 | # We produce "abcd e" | ||
41 | |||
21 | echo Finished | 42 | echo Finished |