diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2016-10-01 20:55:02 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2016-10-01 20:55:02 +0200 |
commit | 88ac97d02dfeb4d3bd9efda45ceb64608cfedd53 (patch) | |
tree | d6ce66f90972a00ff95f811bd10a34b89bb7ea6b /shell | |
parent | c4d4380a0700542796887b2e6dbd41e9a7916997 (diff) | |
download | busybox-w32-88ac97d02dfeb4d3bd9efda45ceb64608cfedd53.tar.gz busybox-w32-88ac97d02dfeb4d3bd9efda45ceb64608cfedd53.tar.bz2 busybox-w32-88ac97d02dfeb4d3bd9efda45ceb64608cfedd53.zip |
ash: [EXPAND] Do not split quoted VSLENGTH and VSTRIM
Upstream patch:
Date: Wed, 8 Oct 2014 15:42:08 +0800
[EXPAND] Do not split quoted VSLENGTH and VSTRIM
Currently VSLENGTH and VSTRIM* are field-split even within quotes.
This is obviously wrong. This patch fixes that.
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 | 52 | ||||
-rw-r--r-- | shell/ash_test/ash-vars/var_wordsplit_ifs2.right | 3 | ||||
-rwxr-xr-x | shell/ash_test/ash-vars/var_wordsplit_ifs2.tests | 13 | ||||
-rw-r--r-- | shell/ash_test/ash-vars/var_wordsplit_ifs3.right | 12 | ||||
-rwxr-xr-x | shell/ash_test/ash-vars/var_wordsplit_ifs3.tests | 5 | ||||
-rw-r--r-- | shell/hush_test/hush-vars/var_wordsplit_ifs2.right | 3 | ||||
-rwxr-xr-x | shell/hush_test/hush-vars/var_wordsplit_ifs2.tests | 13 | ||||
-rw-r--r-- | shell/hush_test/hush-vars/var_wordsplit_ifs3.right | 12 | ||||
-rwxr-xr-x | shell/hush_test/hush-vars/var_wordsplit_ifs3.tests | 5 |
9 files changed, 88 insertions, 30 deletions
diff --git a/shell/ash.c b/shell/ash.c index 56dbcb7d1..d830e3962 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -6753,7 +6753,7 @@ varvalue(char *name, int varflags, int flags, struct strlist *var_str_list, int | |||
6753 | * input string. | 6753 | * input string. |
6754 | */ | 6754 | */ |
6755 | static char * | 6755 | static char * |
6756 | evalvar(char *p, int flags, struct strlist *var_str_list) | 6756 | evalvar(char *p, int flag, struct strlist *var_str_list) |
6757 | { | 6757 | { |
6758 | char varflags; | 6758 | char varflags; |
6759 | char subtype; | 6759 | char subtype; |
@@ -6767,7 +6767,7 @@ evalvar(char *p, int flags, struct strlist *var_str_list) | |||
6767 | 6767 | ||
6768 | varflags = (unsigned char) *p++; | 6768 | varflags = (unsigned char) *p++; |
6769 | subtype = varflags & VSTYPE; | 6769 | subtype = varflags & VSTYPE; |
6770 | quoted = flags & EXP_QUOTED; | 6770 | quoted = flag & EXP_QUOTED; |
6771 | var = p; | 6771 | var = p; |
6772 | easy = (!quoted || (*var == '@' && shellparam.nparam)); | 6772 | easy = (!quoted || (*var == '@' && shellparam.nparam)); |
6773 | nulonly = easy; | 6773 | nulonly = easy; |
@@ -6775,7 +6775,7 @@ evalvar(char *p, int flags, struct strlist *var_str_list) | |||
6775 | p = strchr(p, '=') + 1; //TODO: use var_end(p)? | 6775 | p = strchr(p, '=') + 1; //TODO: use var_end(p)? |
6776 | 6776 | ||
6777 | again: | 6777 | again: |
6778 | varlen = varvalue(var, varflags, flags, var_str_list, &nulonly); | 6778 | varlen = varvalue(var, varflags, flag, var_str_list, &nulonly); |
6779 | if (varflags & VSNUL) | 6779 | if (varflags & VSNUL) |
6780 | varlen--; | 6780 | varlen--; |
6781 | 6781 | ||
@@ -6789,36 +6789,27 @@ evalvar(char *p, int flags, struct strlist *var_str_list) | |||
6789 | if (varlen < 0) { | 6789 | if (varlen < 0) { |
6790 | argstr( | 6790 | argstr( |
6791 | p, | 6791 | p, |
6792 | flags | EXP_TILDE | EXP_WORD, | 6792 | flag | EXP_TILDE | EXP_WORD, |
6793 | var_str_list | 6793 | var_str_list |
6794 | ); | 6794 | ); |
6795 | goto end; | 6795 | goto end; |
6796 | } | 6796 | } |
6797 | if (easy) | 6797 | goto record; |
6798 | goto record; | ||
6799 | goto end; | ||
6800 | } | 6798 | } |
6801 | 6799 | ||
6802 | if (subtype == VSASSIGN || subtype == VSQUESTION) { | 6800 | if (subtype == VSASSIGN || subtype == VSQUESTION) { |
6803 | if (varlen < 0) { | 6801 | if (varlen >= 0) |
6804 | if (subevalvar(p, var, /* strloc: */ 0, | ||
6805 | subtype, startloc, varflags, | ||
6806 | /* quotes: */ flags & ~QUOTES_ESC, | ||
6807 | var_str_list) | ||
6808 | ) { | ||
6809 | varflags &= ~VSNUL; | ||
6810 | /* | ||
6811 | * Remove any recorded regions beyond | ||
6812 | * start of variable | ||
6813 | */ | ||
6814 | removerecordregions(startloc); | ||
6815 | goto again; | ||
6816 | } | ||
6817 | goto end; | ||
6818 | } | ||
6819 | if (easy) | ||
6820 | goto record; | 6802 | goto record; |
6821 | goto end; | 6803 | |
6804 | subevalvar(p, var, 0, subtype, startloc, varflags, | ||
6805 | flag & ~QUOTES_ESC, var_str_list); | ||
6806 | varflags &= ~VSNUL; | ||
6807 | /* | ||
6808 | * Remove any recorded regions beyond | ||
6809 | * start of variable | ||
6810 | */ | ||
6811 | removerecordregions(startloc); | ||
6812 | goto again; | ||
6822 | } | 6813 | } |
6823 | 6814 | ||
6824 | if (varlen < 0 && uflag) | 6815 | if (varlen < 0 && uflag) |
@@ -6830,8 +6821,10 @@ evalvar(char *p, int flags, struct strlist *var_str_list) | |||
6830 | } | 6821 | } |
6831 | 6822 | ||
6832 | if (subtype == VSNORMAL) { | 6823 | if (subtype == VSNORMAL) { |
6833 | if (easy) | 6824 | record: |
6834 | goto record; | 6825 | if (!easy) |
6826 | goto end; | ||
6827 | recordregion(startloc, expdest - (char *)stackblock(), nulonly); | ||
6835 | goto end; | 6828 | goto end; |
6836 | } | 6829 | } |
6837 | 6830 | ||
@@ -6860,7 +6853,7 @@ evalvar(char *p, int flags, struct strlist *var_str_list) | |||
6860 | STPUTC('\0', expdest); | 6853 | STPUTC('\0', expdest); |
6861 | patloc = expdest - (char *)stackblock(); | 6854 | patloc = expdest - (char *)stackblock(); |
6862 | if (NULL == subevalvar(p, /* varname: */ NULL, patloc, subtype, | 6855 | if (NULL == subevalvar(p, /* varname: */ NULL, patloc, subtype, |
6863 | startloc, varflags, flags, var_str_list)) { | 6856 | startloc, varflags, flag, var_str_list)) { |
6864 | int amount = expdest - ( | 6857 | int amount = expdest - ( |
6865 | (char *)stackblock() + patloc - 1 | 6858 | (char *)stackblock() + patloc - 1 |
6866 | ); | 6859 | ); |
@@ -6868,8 +6861,7 @@ evalvar(char *p, int flags, struct strlist *var_str_list) | |||
6868 | } | 6861 | } |
6869 | /* Remove any recorded regions beyond start of variable */ | 6862 | /* Remove any recorded regions beyond start of variable */ |
6870 | removerecordregions(startloc); | 6863 | removerecordregions(startloc); |
6871 | record: | 6864 | goto record; |
6872 | recordregion(startloc, expdest - (char *)stackblock(), nulonly); | ||
6873 | } | 6865 | } |
6874 | 6866 | ||
6875 | end: | 6867 | end: |
diff --git a/shell/ash_test/ash-vars/var_wordsplit_ifs2.right b/shell/ash_test/ash-vars/var_wordsplit_ifs2.right new file mode 100644 index 000000000..c234193fe --- /dev/null +++ b/shell/ash_test/ash-vars/var_wordsplit_ifs2.right | |||
@@ -0,0 +1,3 @@ | |||
1 | Unquoted:<1> | ||
2 | Unquoted:<3> | ||
3 | Quoted:<123> | ||
diff --git a/shell/ash_test/ash-vars/var_wordsplit_ifs2.tests b/shell/ash_test/ash-vars/var_wordsplit_ifs2.tests new file mode 100755 index 000000000..47523549c --- /dev/null +++ b/shell/ash_test/ash-vars/var_wordsplit_ifs2.tests | |||
@@ -0,0 +1,13 @@ | |||
1 | # 123 chars long | ||
2 | a="\ | ||
3 | 01234567890123456789\ | ||
4 | 01234567890123456789\ | ||
5 | 01234567890123456789\ | ||
6 | 01234567890123456789\ | ||
7 | 01234567890123456789\ | ||
8 | 0123456789\ | ||
9 | 0123456789\ | ||
10 | 012" | ||
11 | |||
12 | IFS=2; for v in ${#a}; do echo Unquoted:"<$v>"; done | ||
13 | IFS=2; for v in "${#a}"; do echo Quoted:"<$v>"; done | ||
diff --git a/shell/ash_test/ash-vars/var_wordsplit_ifs3.right b/shell/ash_test/ash-vars/var_wordsplit_ifs3.right new file mode 100644 index 000000000..5ab72e1cd --- /dev/null +++ b/shell/ash_test/ash-vars/var_wordsplit_ifs3.right | |||
@@ -0,0 +1,12 @@ | |||
1 | Unquoted%:<q> | ||
2 | Unquoted%:<w> | ||
3 | Unquoted%:<e> | ||
4 | Unquoted%:<r> | ||
5 | Unquoted%:<t> | ||
6 | Unquoted#:<w> | ||
7 | Unquoted#:<e> | ||
8 | Unquoted#:<r> | ||
9 | Unquoted#:<t> | ||
10 | Unquoted#:<y> | ||
11 | Quoted%:<q w e r t > | ||
12 | Quoted#:< w e r t y> | ||
diff --git a/shell/ash_test/ash-vars/var_wordsplit_ifs3.tests b/shell/ash_test/ash-vars/var_wordsplit_ifs3.tests new file mode 100755 index 000000000..4aa65574a --- /dev/null +++ b/shell/ash_test/ash-vars/var_wordsplit_ifs3.tests | |||
@@ -0,0 +1,5 @@ | |||
1 | a="q w e r t y" | ||
2 | for v in ${a%y}; do echo Unquoted%:"<$v>"; done | ||
3 | for v in ${a#q}; do echo Unquoted#:"<$v>"; done | ||
4 | for v in "${a%y}"; do echo Quoted%:"<$v>"; done | ||
5 | for v in "${a#q}"; do echo Quoted#:"<$v>"; done | ||
diff --git a/shell/hush_test/hush-vars/var_wordsplit_ifs2.right b/shell/hush_test/hush-vars/var_wordsplit_ifs2.right new file mode 100644 index 000000000..c234193fe --- /dev/null +++ b/shell/hush_test/hush-vars/var_wordsplit_ifs2.right | |||
@@ -0,0 +1,3 @@ | |||
1 | Unquoted:<1> | ||
2 | Unquoted:<3> | ||
3 | Quoted:<123> | ||
diff --git a/shell/hush_test/hush-vars/var_wordsplit_ifs2.tests b/shell/hush_test/hush-vars/var_wordsplit_ifs2.tests new file mode 100755 index 000000000..47523549c --- /dev/null +++ b/shell/hush_test/hush-vars/var_wordsplit_ifs2.tests | |||
@@ -0,0 +1,13 @@ | |||
1 | # 123 chars long | ||
2 | a="\ | ||
3 | 01234567890123456789\ | ||
4 | 01234567890123456789\ | ||
5 | 01234567890123456789\ | ||
6 | 01234567890123456789\ | ||
7 | 01234567890123456789\ | ||
8 | 0123456789\ | ||
9 | 0123456789\ | ||
10 | 012" | ||
11 | |||
12 | IFS=2; for v in ${#a}; do echo Unquoted:"<$v>"; done | ||
13 | IFS=2; for v in "${#a}"; do echo Quoted:"<$v>"; done | ||
diff --git a/shell/hush_test/hush-vars/var_wordsplit_ifs3.right b/shell/hush_test/hush-vars/var_wordsplit_ifs3.right new file mode 100644 index 000000000..5ab72e1cd --- /dev/null +++ b/shell/hush_test/hush-vars/var_wordsplit_ifs3.right | |||
@@ -0,0 +1,12 @@ | |||
1 | Unquoted%:<q> | ||
2 | Unquoted%:<w> | ||
3 | Unquoted%:<e> | ||
4 | Unquoted%:<r> | ||
5 | Unquoted%:<t> | ||
6 | Unquoted#:<w> | ||
7 | Unquoted#:<e> | ||
8 | Unquoted#:<r> | ||
9 | Unquoted#:<t> | ||
10 | Unquoted#:<y> | ||
11 | Quoted%:<q w e r t > | ||
12 | Quoted#:< w e r t y> | ||
diff --git a/shell/hush_test/hush-vars/var_wordsplit_ifs3.tests b/shell/hush_test/hush-vars/var_wordsplit_ifs3.tests new file mode 100755 index 000000000..4aa65574a --- /dev/null +++ b/shell/hush_test/hush-vars/var_wordsplit_ifs3.tests | |||
@@ -0,0 +1,5 @@ | |||
1 | a="q w e r t y" | ||
2 | for v in ${a%y}; do echo Unquoted%:"<$v>"; done | ||
3 | for v in ${a#q}; do echo Unquoted#:"<$v>"; done | ||
4 | for v in "${a%y}"; do echo Quoted%:"<$v>"; done | ||
5 | for v in "${a#q}"; do echo Quoted#:"<$v>"; done | ||