diff options
author | Denys Vlasenko | 2016-10-01 20:55:02 +0200 |
---|---|---|
committer | Denys Vlasenko | 2016-10-01 20:55:02 +0200 |
commit | 88ac97d02dfeb4d3bd9efda45ceb64608cfedd53 (patch) | |
tree | d6ce66f90972a00ff95f811bd10a34b89bb7ea6b /shell | |
parent | c4d4380a0700542796887b2e6dbd41e9a7916997 (diff) | |
download | busybox-88ac97d02dfeb4d3bd9efda45ceb64608cfedd53.zip busybox-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.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 56dbcb7..d830e39 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 0000000..c234193 --- /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 0000000..4752354 --- /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 0000000..5ab72e1 --- /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 0000000..4aa6557 --- /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 0000000..c234193 --- /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 0000000..4752354 --- /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 0000000..5ab72e1 --- /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 0000000..4aa6557 --- /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 |