diff options
author | Denys Vlasenko | 2016-10-26 15:56:53 +0200 |
---|---|---|
committer | Denys Vlasenko | 2016-10-26 15:56:53 +0200 |
commit | f15aa57a7f5edcbf3098873b8798c0ea7f496ed7 (patch) | |
tree | 5641162328f080297bd9a27cf50730dbb3a8f604 /shell/ash.c | |
parent | e19923f6652a638ac39c84012e97f52cf5a7568e (diff) | |
download | busybox-f15aa57a7f5edcbf3098873b8798c0ea7f496ed7.zip busybox-f15aa57a7f5edcbf3098873b8798c0ea7f496ed7.tar.gz |
ash: [PARSER] Fix parsing of ${##1}
Upstream commit:
Date: Thu, 4 Oct 2007 22:15:10 +0800
[PARSER] Fix parsing of ${##1}
Previously dash treated ${##1} as a length operation. This patch fixes that.
Test case:
set -- a
echo ${##1}OK
Old result:
1OK
New result:
OK
This was a real bug in ash (but not in hush).
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'shell/ash.c')
-rw-r--r-- | shell/ash.c | 28 |
1 files changed, 18 insertions, 10 deletions
diff --git a/shell/ash.c b/shell/ash.c index b404449..2cebfe2 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -11728,16 +11728,9 @@ parsesub: { subtype = VSNORMAL; if (c == '{') { c = pgetc_eatbnl(); - if (c == '#') { - c = pgetc_eatbnl(); - if (c == '}') - c = '#'; /* ${#} - same as $# */ - else - subtype = VSLENGTH; /* ${#VAR} */ - } else { - subtype = 0; - } + subtype = 0; } + varname: if (c <= 255 /* not PEOA or PEOF */ && is_name(c)) { /* $[{[#]]NAME[}] */ do { @@ -11752,8 +11745,23 @@ parsesub: { } while (isdigit(c)); } else if (is_special(c)) { /* $[{[#]]<specialchar>[}] */ - USTPUTC(c, out); + int cc = c; + c = pgetc_eatbnl(); + if (!subtype && cc == '#') { + subtype = VSLENGTH; + if (c == '_' || isalnum(c)) + goto varname; + cc = c; + c = pgetc_eatbnl(); + if (cc == '}' || c != '}') { + pungetc(); + subtype = 0; + c = cc; + cc = '#'; + } + } + USTPUTC(cc, out); } else { goto badsub; } |