aboutsummaryrefslogtreecommitdiff
path: root/shell
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2016-10-01 20:55:02 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2016-10-01 20:55:02 +0200
commit88ac97d02dfeb4d3bd9efda45ceb64608cfedd53 (patch)
treed6ce66f90972a00ff95f811bd10a34b89bb7ea6b /shell
parentc4d4380a0700542796887b2e6dbd41e9a7916997 (diff)
downloadbusybox-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.c52
-rw-r--r--shell/ash_test/ash-vars/var_wordsplit_ifs2.right3
-rwxr-xr-xshell/ash_test/ash-vars/var_wordsplit_ifs2.tests13
-rw-r--r--shell/ash_test/ash-vars/var_wordsplit_ifs3.right12
-rwxr-xr-xshell/ash_test/ash-vars/var_wordsplit_ifs3.tests5
-rw-r--r--shell/hush_test/hush-vars/var_wordsplit_ifs2.right3
-rwxr-xr-xshell/hush_test/hush-vars/var_wordsplit_ifs2.tests13
-rw-r--r--shell/hush_test/hush-vars/var_wordsplit_ifs3.right12
-rwxr-xr-xshell/hush_test/hush-vars/var_wordsplit_ifs3.tests5
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 */
6755static char * 6755static char *
6756evalvar(char *p, int flags, struct strlist *var_str_list) 6756evalvar(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 @@
1Unquoted:<1>
2Unquoted:<3>
3Quoted:<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
2a="\
301234567890123456789\
401234567890123456789\
501234567890123456789\
601234567890123456789\
701234567890123456789\
80123456789\
90123456789\
10012"
11
12IFS=2; for v in ${#a}; do echo Unquoted:"<$v>"; done
13IFS=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 @@
1Unquoted%:<q>
2Unquoted%:<w>
3Unquoted%:<e>
4Unquoted%:<r>
5Unquoted%:<t>
6Unquoted#:<w>
7Unquoted#:<e>
8Unquoted#:<r>
9Unquoted#:<t>
10Unquoted#:<y>
11Quoted%:<q w e r t >
12Quoted#:< 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 @@
1a="q w e r t y"
2for v in ${a%y}; do echo Unquoted%:"<$v>"; done
3for v in ${a#q}; do echo Unquoted#:"<$v>"; done
4for v in "${a%y}"; do echo Quoted%:"<$v>"; done
5for 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 @@
1Unquoted:<1>
2Unquoted:<3>
3Quoted:<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
2a="\
301234567890123456789\
401234567890123456789\
501234567890123456789\
601234567890123456789\
701234567890123456789\
80123456789\
90123456789\
10012"
11
12IFS=2; for v in ${#a}; do echo Unquoted:"<$v>"; done
13IFS=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 @@
1Unquoted%:<q>
2Unquoted%:<w>
3Unquoted%:<e>
4Unquoted%:<r>
5Unquoted%:<t>
6Unquoted#:<w>
7Unquoted#:<e>
8Unquoted#:<r>
9Unquoted#:<t>
10Unquoted#:<y>
11Quoted%:<q w e r t >
12Quoted#:< 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 @@
1a="q w e r t y"
2for v in ${a%y}; do echo Unquoted%:"<$v>"; done
3for v in ${a#q}; do echo Unquoted#:"<$v>"; done
4for v in "${a%y}"; do echo Quoted%:"<$v>"; done
5for v in "${a#q}"; do echo Quoted#:"<$v>"; done