ash: expand: Fix multiple issues with EXP_DISCARD in evalvar
No binary (build failed)
—
(log yok)
| @@ -7454,6 +7454,7 @@ evalvar(char *p, int flag) | |
| int patloc; | |
| int startloc; | |
| ssize_t varlen; | |
| + | int discard; |
| int quoted; | |
| varflags = (unsigned char) *p++; | |
| @@ -7469,33 +7470,31 @@ evalvar(char *p, int flag) | |
| if (varflags & VSNUL) | |
| varlen--; | |
| + | discard = varlen < 0 ? EXP_DISCARD : 0; |
| + | |
| switch (subtype) { | |
| case VSPLUS: | |
| - | varlen = -1 - varlen; |
| + | discard ^= EXP_DISCARD; |
| /* fall through */ | |
| case 0: | |
| case VSMINUS: | |
| - | p = argstr(p, flag | EXP_TILDE | EXP_WORD); |
| - | if (varlen < 0) |
| - | return p; |
| + | p = argstr(p, flag | EXP_TILDE | EXP_WORD | (discard ^ EXP_DISCARD)); |
| goto record; | |
| case VSASSIGN: | |
| case VSQUESTION: | |
| - | if (varlen >= 0) |
| - | goto record; |
| - | |
| p = subevalvar(p, var, 0, startloc, varflags, | |
| - | flag & ~QUOTES_ESC); |
| + | (flag & ~QUOTES_ESC) | (discard ^ EXP_DISCARD)); |
| - | if (flag & EXP_DISCARD) |
| - | return p; |
| + | if ((flag | ~discard) & EXP_DISCARD) |
| + | goto record; |
| varflags &= ~VSNUL; | |
| + | subtype = VSNORMAL; |
| goto again; | |
| } | |
| - | if (varlen < 0 && uflag) |
| + | if ((discard & ~flag) && uflag) |
| varunset(p, var, 0, 0); | |
| if (subtype == VSLENGTH) { | |
| @@ -7503,7 +7502,7 @@ evalvar(char *p, int flag) | |
| if (flag & EXP_DISCARD) | |
| return p; | |
| cvtnum(varlen > 0 ? varlen : 0, flag); | |
| - | goto record; |
| + | goto really_record; |
| } | |
| if (subtype == VSNORMAL) | |
| @@ -7528,7 +7527,7 @@ evalvar(char *p, int flag) | |
| } | |
| #endif | |
| - | flag |= varlen < 0 ? EXP_DISCARD : 0; |
| + | flag |= discard; |
| if (!(flag & EXP_DISCARD)) { | |
| /* | |
| * Terminate the string and start recording the pattern | |
| @@ -7541,9 +7540,10 @@ evalvar(char *p, int flag) | |
| p = subevalvar(p, NULL, patloc, startloc, varflags, flag); | |
| record: | |
| - | if (flag & EXP_DISCARD) |
| + | if ((flag | discard) & EXP_DISCARD) |
| return p; | |
| + | really_record: |
| if (quoted) { | |
| quoted = *var == '@' && shellparam.nparam; | |
| if (!quoted) | |