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 | ||
