diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2016-07-25 03:56:00 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2016-07-25 03:56:00 +0200 |
commit | f8ddbe1ccce9eceaaac28b4b1aa71631fcc56db6 (patch) | |
tree | 0782f9ae0ab8bfb74ad8c3fca455f2dcd4de6b33 | |
parent | 0fb0045aa9261be1dda49dfdfb95cbc585402a8b (diff) | |
download | busybox-w32-f8ddbe1ccce9eceaaac28b4b1aa71631fcc56db6.tar.gz busybox-w32-f8ddbe1ccce9eceaaac28b4b1aa71631fcc56db6.tar.bz2 busybox-w32-f8ddbe1ccce9eceaaac28b4b1aa71631fcc56db6.zip |
ash: fix handling of ${VAR: -2}
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-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 4f6376f78..496167fbe 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -6323,6 +6323,8 @@ subevalvar(char *p, char *varname, int strloc, int subtype, | |||
6323 | 6323 | ||
6324 | #if ENABLE_ASH_BASH_COMPAT | 6324 | #if ENABLE_ASH_BASH_COMPAT |
6325 | case VSSUBSTR: | 6325 | case VSSUBSTR: |
6326 | //TODO: support more general format ${v:EXPR:EXPR}, | ||
6327 | // where EXPR follows $(()) rules | ||
6326 | loc = str = stackblock() + strloc; | 6328 | loc = str = stackblock() + strloc; |
6327 | /* Read POS in ${var:POS:LEN} */ | 6329 | /* Read POS in ${var:POS:LEN} */ |
6328 | pos = atoi(loc); /* number(loc) errors out on "1:4" */ | 6330 | pos = atoi(loc); /* number(loc) errors out on "1:4" */ |
@@ -11577,15 +11579,18 @@ parsesub: { | |||
11577 | STPUTC('=', out); | 11579 | STPUTC('=', out); |
11578 | flags = 0; | 11580 | flags = 0; |
11579 | if (subtype == 0) { | 11581 | if (subtype == 0) { |
11582 | static const char types[] ALIGN1 = "}-+?="; | ||
11580 | /* ${VAR...} but not $VAR or ${#VAR} */ | 11583 | /* ${VAR...} but not $VAR or ${#VAR} */ |
11581 | /* c == first char after VAR */ | 11584 | /* c == first char after VAR */ |
11582 | switch (c) { | 11585 | switch (c) { |
11583 | case ':': | 11586 | case ':': |
11584 | c = pgetc(); | 11587 | c = pgetc(); |
11585 | #if ENABLE_ASH_BASH_COMPAT | 11588 | #if ENABLE_ASH_BASH_COMPAT |
11586 | if (c == ':' || c == '$' || isdigit(c)) { | 11589 | /* This check is only needed to not misinterpret |
11587 | //TODO: support more general format ${v:EXPR:EXPR}, | 11590 | * ${VAR:-WORD}, ${VAR:+WORD}, ${VAR:=WORD}, ${VAR:?WORD} |
11588 | // where EXPR follows $(()) rules | 11591 | * constructs. |
11592 | */ | ||
11593 | if (!strchr(types, c)) { | ||
11589 | subtype = VSSUBSTR; | 11594 | subtype = VSSUBSTR; |
11590 | pungetc(); | 11595 | pungetc(); |
11591 | break; /* "goto do_pungetc" is bigger (!) */ | 11596 | break; /* "goto do_pungetc" is bigger (!) */ |
@@ -11594,7 +11599,6 @@ parsesub: { | |||
11594 | flags = VSNUL; | 11599 | flags = VSNUL; |
11595 | /*FALLTHROUGH*/ | 11600 | /*FALLTHROUGH*/ |
11596 | default: { | 11601 | default: { |
11597 | static const char types[] ALIGN1 = "}-+?="; | ||
11598 | const char *p = strchr(types, c); | 11602 | const char *p = strchr(types, c); |
11599 | if (p == NULL) | 11603 | if (p == NULL) |
11600 | goto badsub; | 11604 | 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 000000000..1965b5c6c --- /dev/null +++ b/shell/ash_test/ash-vars/var_bash1a.right | |||
@@ -0,0 +1,6 @@ | |||
1 | parameter 'abcdef' | ||
2 | varoffset2 'cdef' | ||
3 | varoffset-2 'ef' | ||
4 | literal '2' 'cdef' | ||
5 | literal '-2' 'abcdef' | ||
6 | 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 000000000..551dd9acc --- /dev/null +++ b/shell/ash_test/ash-vars/var_bash1a.tests | |||
@@ -0,0 +1,11 @@ | |||
1 | parameter=abcdef | ||
2 | offset=2 | ||
3 | noffset=-2 | ||
4 | echo "parameter '${parameter}'" | ||
5 | echo "varoffset2 '${parameter:${offset}}'" | ||
6 | echo "varoffset-2 '${parameter:${noffset}}'" | ||
7 | echo "literal '2' '${parameter:2}'" | ||
8 | # This is not inrpreted as ${VAR:POS{:LEN}}, | ||
9 | # but as ${VAR:=WORD} - if VAR is unset or null, substitute WORD | ||
10 | echo "literal '-2' '${parameter:-2}'" | ||
11 | echo "literal ' -2' '${parameter: -2}'" | ||