From 88ac97d02dfeb4d3bd9efda45ceb64608cfedd53 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sat, 1 Oct 2016 20:55:02 +0200 Subject: [PATCH] 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 Signed-off-by: Denys Vlasenko --- shell/ash.c | 52 ++++++++----------- .../ash-vars/var_wordsplit_ifs2.right | 3 ++ .../ash-vars/var_wordsplit_ifs2.tests | 13 +++++ .../ash-vars/var_wordsplit_ifs3.right | 12 +++++ .../ash-vars/var_wordsplit_ifs3.tests | 5 ++ .../hush-vars/var_wordsplit_ifs2.right | 3 ++ .../hush-vars/var_wordsplit_ifs2.tests | 13 +++++ .../hush-vars/var_wordsplit_ifs3.right | 12 +++++ .../hush-vars/var_wordsplit_ifs3.tests | 5 ++ 9 files changed, 88 insertions(+), 30 deletions(-) create mode 100644 shell/ash_test/ash-vars/var_wordsplit_ifs2.right create mode 100755 shell/ash_test/ash-vars/var_wordsplit_ifs2.tests create mode 100644 shell/ash_test/ash-vars/var_wordsplit_ifs3.right create mode 100755 shell/ash_test/ash-vars/var_wordsplit_ifs3.tests create mode 100644 shell/hush_test/hush-vars/var_wordsplit_ifs2.right create mode 100755 shell/hush_test/hush-vars/var_wordsplit_ifs2.tests create mode 100644 shell/hush_test/hush-vars/var_wordsplit_ifs3.right create mode 100755 shell/hush_test/hush-vars/var_wordsplit_ifs3.tests 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%: +Unquoted%: +Unquoted%: +Unquoted%: +Unquoted%: +Unquoted#: +Unquoted#: +Unquoted#: +Unquoted#: +Unquoted#: +Quoted%: +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%: +Unquoted%: +Unquoted%: +Unquoted%: +Unquoted%: +Unquoted#: +Unquoted#: +Unquoted#: +Unquoted#: +Unquoted#: +Quoted%: +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 -- 2.25.1