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>
This commit is contained in:
Denys Vlasenko 2016-10-26 15:56:53 +02:00
parent e19923f665
commit f15aa57a7f
5 changed files with 38 additions and 10 deletions

View File

@ -11728,16 +11728,9 @@ parsesub: {
subtype = VSNORMAL; subtype = VSNORMAL;
if (c == '{') { if (c == '{') {
c = pgetc_eatbnl(); 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)) { if (c <= 255 /* not PEOA or PEOF */ && is_name(c)) {
/* $[{[#]]NAME[}] */ /* $[{[#]]NAME[}] */
do { do {
@ -11752,8 +11745,23 @@ parsesub: {
} while (isdigit(c)); } while (isdigit(c));
} else if (is_special(c)) { } else if (is_special(c)) {
/* $[{[#]]<specialchar>[}] */ /* $[{[#]]<specialchar>[}] */
USTPUTC(c, out); int cc = c;
c = pgetc_eatbnl(); 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 { } else {
goto badsub; goto badsub;
} }

View File

@ -7,3 +7,6 @@ Make sure len parsing doesnt break arg count
Testing len op Testing len op
4 3 2 1 0 0 4 3 2 1 0 0
0 3 0 0 3 0
Nothing:
Nothing:
One:1

View File

@ -15,3 +15,10 @@ unset e
f=abc f=abc
g= g=
echo ${#e} ${#f} ${#g} echo ${#e} ${#f} ${#g}
set -- a
# This must be interpreted as: $# ("1"), then remove trailing "1".
# IOW: empty result.
echo Nothing:${##1}
echo Nothing:${#%1}
echo One:${##x}

View File

@ -7,3 +7,6 @@ Make sure len parsing doesnt break arg count
Testing len op Testing len op
4 3 2 1 0 0 4 3 2 1 0 0
0 3 0 0 3 0
Nothing:
Nothing:
One:1

View File

@ -15,3 +15,10 @@ unset e
f=abc f=abc
g= g=
echo ${#e} ${#f} ${#g} echo ${#e} ${#f} ${#g}
set -- a
# This must be interpreted as: $# ("1"), then remove trailing "1".
# IOW: empty result.
echo Nothing:${##1}
echo Nothing:${#%1}
echo One:${##x}