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-88ac97d02dfeb4d3bd9efda45ceb64608cfedd53.tar.gz
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
* input string.
*/
static char *
-evalvar(char *p, int flags, struct strlist *var_str_list)
+evalvar(char *p, int flag, struct strlist *var_str_list)
{
char varflags;
char subtype;
@@ -6767,7 +6767,7 @@ evalvar(char *p, int flags, struct strlist *var_str_list)
varflags = (unsigned char) *p++;
subtype = varflags & VSTYPE;
- quoted = flags & EXP_QUOTED;
+ quoted = flag & EXP_QUOTED;
var = p;
easy = (!quoted || (*var == '@' && shellparam.nparam));
nulonly = easy;
@@ -6775,7 +6775,7 @@ evalvar(char *p, int flags, struct strlist *var_str_list)
p = strchr(p, '=') + 1; //TODO: use var_end(p)?
again:
- varlen = varvalue(var, varflags, flags, var_str_list, &nulonly);
+ varlen = varvalue(var, varflags, flag, var_str_list, &nulonly);
if (varflags & VSNUL)
varlen--;
@@ -6789,36 +6789,27 @@ evalvar(char *p, int flags, struct strlist *var_str_list)
if (varlen < 0) {
argstr(
p,
- flags | EXP_TILDE | EXP_WORD,
+ flag | EXP_TILDE | EXP_WORD,
var_str_list
);
goto end;
}
- if (easy)
- goto record;
- goto end;
+ goto record;
}
if (subtype == VSASSIGN || subtype == VSQUESTION) {
- if (varlen < 0) {
- if (subevalvar(p, var, /* strloc: */ 0,
- subtype, startloc, varflags,
- /* quotes: */ flags & ~QUOTES_ESC,
- var_str_list)
- ) {
- varflags &= ~VSNUL;
- /*
- * Remove any recorded regions beyond
- * start of variable
- */
- removerecordregions(startloc);
- goto again;
- }
- goto end;
- }
- if (easy)
+ if (varlen >= 0)
goto record;
- goto end;
+
+ subevalvar(p, var, 0, subtype, startloc, varflags,
+ flag & ~QUOTES_ESC, var_str_list);
+ varflags &= ~VSNUL;
+ /*
+ * Remove any recorded regions beyond
+ * start of variable
+ */
+ removerecordregions(startloc);
+ goto again;
}
if (varlen < 0 && uflag)
@@ -6830,8 +6821,10 @@ evalvar(char *p, int flags, struct strlist *var_str_list)
}
if (subtype == VSNORMAL) {
- if (easy)
- goto record;
+ record:
+ if (!easy)
+ goto end;
+ recordregion(startloc, expdest - (char *)stackblock(), nulonly);
goto end;
}
@@ -6860,7 +6853,7 @@ evalvar(char *p, int flags, struct strlist *var_str_list)
STPUTC('\0', expdest);
patloc = expdest - (char *)stackblock();
if (NULL == subevalvar(p, /* varname: */ NULL, patloc, subtype,
- startloc, varflags, flags, var_str_list)) {
+ startloc, varflags, flag, var_str_list)) {
int amount = expdest - (
(char *)stackblock() + patloc - 1
);
@@ -6868,8 +6861,7 @@ evalvar(char *p, int flags, struct strlist *var_str_list)
}
/* Remove any recorded regions beyond start of variable */
removerecordregions(startloc);
- record:
- recordregion(startloc, expdest - (char *)stackblock(), nulonly);
+ goto record;
}
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 @@
+Unquoted:<1>
+Unquoted:<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 @@
+# 123 chars long
+a="\
+01234567890123456789\
+01234567890123456789\
+01234567890123456789\
+01234567890123456789\
+01234567890123456789\
+0123456789\
+0123456789\
+012"
+
+IFS=2; for v in ${#a}; do echo Unquoted:"<$v>"; done
+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 @@
+Unquoted%:<q>
+Unquoted%:<w>
+Unquoted%:<e>
+Unquoted%:<r>
+Unquoted%:<t>
+Unquoted#:<w>
+Unquoted#:<e>
+Unquoted#:<r>
+Unquoted#:<t>
+Unquoted#:<y>
+Quoted%:<q w e r t >
+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 @@
+a="q w e r t y"
+for v in ${a%y}; do echo Unquoted%:"<$v>"; done
+for v in ${a#q}; do echo Unquoted#:"<$v>"; done
+for v in "${a%y}"; do echo Quoted%:"<$v>"; done
+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 @@
+Unquoted:<1>
+Unquoted:<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 @@
+# 123 chars long
+a="\
+01234567890123456789\
+01234567890123456789\
+01234567890123456789\
+01234567890123456789\
+01234567890123456789\
+0123456789\
+0123456789\
+012"
+
+IFS=2; for v in ${#a}; do echo Unquoted:"<$v>"; done
+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 @@
+Unquoted%:<q>
+Unquoted%:<w>
+Unquoted%:<e>
+Unquoted%:<r>
+Unquoted%:<t>
+Unquoted#:<w>
+Unquoted#:<e>
+Unquoted#:<r>
+Unquoted#:<t>
+Unquoted#:<y>
+Quoted%:<q w e r t >
+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 @@
+a="q w e r t y"
+for v in ${a%y}; do echo Unquoted%:"<$v>"; done
+for v in ${a#q}; do echo Unquoted#:"<$v>"; done
+for v in "${a%y}"; do echo Quoted%:"<$v>"; done
+for v in "${a#q}"; do echo Quoted#:"<$v>"; done