diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2016-10-01 20:35:10 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2016-10-01 20:35:10 +0200 |
commit | c4d4380a0700542796887b2e6dbd41e9a7916997 (patch) | |
tree | fd6010b5cc072a098e868dfd9bec105ca9bbabcd /shell/ash.c | |
parent | a2633aa8197a866a7c00406f7eb7e9c9b4554166 (diff) | |
download | busybox-w32-c4d4380a0700542796887b2e6dbd41e9a7916997.tar.gz busybox-w32-c4d4380a0700542796887b2e6dbd41e9a7916997.tar.bz2 busybox-w32-c4d4380a0700542796887b2e6dbd41e9a7916997.zip |
ash: [EXPAND] Split unquoted $@/$* correctly when IFS is set but empty
Upstream commit:
Date: Wed, 8 Oct 2014 15:24:23 +0800
[EXPAND] Split unquoted $@/$* correctly when IFS is set but empty
Currently we do not field-split $@/$* when it isn't quoted and IFS
is set but empty. This is obviously wrong. This patch fixes this.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'shell/ash.c')
-rw-r--r-- | shell/ash.c | 14 |
1 files changed, 9 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: |