diff options
author | Denys Vlasenko | 2016-07-25 03:56:00 +0200 |
---|---|---|
committer | Denys Vlasenko | 2016-07-25 03:56:00 +0200 |
commit | f8ddbe1ccce9eceaaac28b4b1aa71631fcc56db6 (patch) | |
tree | 0782f9ae0ab8bfb74ad8c3fca455f2dcd4de6b33 /shell | |
parent | 0fb0045aa9261be1dda49dfdfb95cbc585402a8b (diff) | |
download | busybox-f8ddbe1ccce9eceaaac28b4b1aa71631fcc56db6.zip busybox-f8ddbe1ccce9eceaaac28b4b1aa71631fcc56db6.tar.gz |
ash: fix handling of ${VAR: -2}
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'shell')
-rw-r--r-- | shell/ash.c | 12 | ||||
-rw-r--r-- | shell/ash_test/ash-vars/var_bash1a.right | 6 | ||||
-rwxr-xr-x | shell/ash_test/ash-vars/var_bash1a.tests | 11 |
3 files changed, 25 insertions, 4 deletions
diff --git a/shell/ash.c b/shell/ash.c index 4f6376f..496167f 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -6323,6 +6323,8 @@ subevalvar(char *p, char *varname, int strloc, int subtype, #if ENABLE_ASH_BASH_COMPAT case VSSUBSTR: +//TODO: support more general format ${v:EXPR:EXPR}, +// where EXPR follows $(()) rules loc = str = stackblock() + strloc; /* Read POS in ${var:POS:LEN} */ pos = atoi(loc); /* number(loc) errors out on "1:4" */ @@ -11577,15 +11579,18 @@ parsesub: { STPUTC('=', out); flags = 0; if (subtype == 0) { + static const char types[] ALIGN1 = "}-+?="; /* ${VAR...} but not $VAR or ${#VAR} */ /* c == first char after VAR */ switch (c) { case ':': c = pgetc(); #if ENABLE_ASH_BASH_COMPAT - if (c == ':' || c == '$' || isdigit(c)) { -//TODO: support more general format ${v:EXPR:EXPR}, -// where EXPR follows $(()) rules + /* This check is only needed to not misinterpret + * ${VAR:-WORD}, ${VAR:+WORD}, ${VAR:=WORD}, ${VAR:?WORD} + * constructs. + */ + if (!strchr(types, c)) { subtype = VSSUBSTR; pungetc(); break; /* "goto do_pungetc" is bigger (!) */ @@ -11594,7 +11599,6 @@ parsesub: { flags = VSNUL; /*FALLTHROUGH*/ default: { - static const char types[] ALIGN1 = "}-+?="; const char *p = strchr(types, c); if (p == NULL) goto badsub; diff --git a/shell/ash_test/ash-vars/var_bash1a.right b/shell/ash_test/ash-vars/var_bash1a.right new file mode 100644 index 0000000..1965b5c --- /dev/null +++ b/shell/ash_test/ash-vars/var_bash1a.right @@ -0,0 +1,6 @@ +parameter 'abcdef' +varoffset2 'cdef' +varoffset-2 'ef' +literal '2' 'cdef' +literal '-2' 'abcdef' +literal ' -2' 'ef' diff --git a/shell/ash_test/ash-vars/var_bash1a.tests b/shell/ash_test/ash-vars/var_bash1a.tests new file mode 100755 index 0000000..551dd9a --- /dev/null +++ b/shell/ash_test/ash-vars/var_bash1a.tests @@ -0,0 +1,11 @@ +parameter=abcdef +offset=2 +noffset=-2 +echo "parameter '${parameter}'" +echo "varoffset2 '${parameter:${offset}}'" +echo "varoffset-2 '${parameter:${noffset}}'" +echo "literal '2' '${parameter:2}'" +# This is not inrpreted as ${VAR:POS{:LEN}}, +# but as ${VAR:=WORD} - if VAR is unset or null, substitute WORD +echo "literal '-2' '${parameter:-2}'" +echo "literal ' -2' '${parameter: -2}'" |