aboutsummaryrefslogtreecommitdiff
path: root/shell
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2016-10-02 02:46:56 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2016-10-02 02:46:56 +0200
commit0aaaa50b4551ab5912ccd95d66d633844eac6d85 (patch)
tree1a1f9e34c690051a678fb048064e4e98cca3536b /shell
parent42eeb255c1c5f35373d3e7bfa892e4f864cf1266 (diff)
downloadbusybox-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.c28
-rw-r--r--shell/ash_test/ash-vars/var_wordsplit_ifs1.right16
-rwxr-xr-xshell/ash_test/ash-vars/var_wordsplit_ifs1.tests21
-rw-r--r--shell/hush_test/hush-vars/var_wordsplit_ifs1.right16
-rwxr-xr-xshell/hush_test/hush-vars/var_wordsplit_ifs1.tests21
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="" "$*"
22Testing: IFS="" "$@" 22Testing: IFS="" "$@"
23.abc. 23.abc.
24.d e. 24.d e.
25Testing: !IFS v=$*
26v='abc d e'
27Testing: !IFS v=$@
28v='abc d e'
29Testing: !IFS v="$*"
30v='abc d e'
31Testing: !IFS v="$@"
32v='abc d e'
33Testing: IFS="" v=$*
34v='abcd e'
35Testing: IFS="" v=$@
36v='abcd e'
37Testing: IFS="" v="$*"
38v='abcd e'
39Testing: IFS="" v="$@"
40v='abcd e'
25Finished 41Finished
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
18echo 'Testing: IFS="" "$@"' 18echo 'Testing: IFS="" "$@"'
19IFS=""; for a in "$@"; do echo ".$a."; done 19IFS=""; for a in "$@"; do echo ".$a."; done
20 20
21echo 'Testing: !IFS v=$*'
22unset IFS; v=$*; echo "v='$v'"
23echo 'Testing: !IFS v=$@'
24unset IFS; v=$@; echo "v='$v'"
25echo 'Testing: !IFS v="$*"'
26unset IFS; v="$*"; echo "v='$v'"
27echo 'Testing: !IFS v="$@"'
28unset IFS; v="$@"; echo "v='$v'"
29
30echo 'Testing: IFS="" v=$*'
31IFS=""; v=$*; echo "v='$v'"
32echo 'Testing: IFS="" v=$@'
33IFS=""; v=$@; echo "v='$v'"
34echo 'Testing: IFS="" v="$*"'
35IFS=""; v="$*"; echo "v='$v'"
36echo 'Testing: IFS="" v="$@"'
37IFS=""; 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
21echo Finished 42echo 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="" "$*"
22Testing: IFS="" "$@" 22Testing: IFS="" "$@"
23.abc. 23.abc.
24.d e. 24.d e.
25Testing: !IFS v=$*
26v='abc d e'
27Testing: !IFS v=$@
28v='abc d e'
29Testing: !IFS v="$*"
30v='abc d e'
31Testing: !IFS v="$@"
32v='abc d e'
33Testing: IFS="" v=$*
34v='abcd e'
35Testing: IFS="" v=$@
36v='abcd e'
37Testing: IFS="" v="$*"
38v='abcd e'
39Testing: IFS="" v="$@"
40v='abcd e'
25Finished 41Finished
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
18echo 'Testing: IFS="" "$@"' 18echo 'Testing: IFS="" "$@"'
19IFS=""; for a in "$@"; do echo ".$a."; done 19IFS=""; for a in "$@"; do echo ".$a."; done
20 20
21echo 'Testing: !IFS v=$*'
22unset IFS; v=$*; echo "v='$v'"
23echo 'Testing: !IFS v=$@'
24unset IFS; v=$@; echo "v='$v'"
25echo 'Testing: !IFS v="$*"'
26unset IFS; v="$*"; echo "v='$v'"
27echo 'Testing: !IFS v="$@"'
28unset IFS; v="$@"; echo "v='$v'"
29
30echo 'Testing: IFS="" v=$*'
31IFS=""; v=$*; echo "v='$v'"
32echo 'Testing: IFS="" v=$@'
33IFS=""; v=$@; echo "v='$v'"
34echo 'Testing: IFS="" v="$*"'
35IFS=""; v="$*"; echo "v='$v'"
36echo 'Testing: IFS="" v="$@"'
37IFS=""; 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
21echo Finished 42echo Finished