On Sun, Sep 02, 2018 at 10:15:50PM +0000, Martijn Dekker wrote:
> Commit 3cd538634f71538370f5af239f342aec48b7470b broke these:
> 
> $ src/dash -c 'unset var; echo ${var+set}'
> set
> $ src/dash -c 'var=; echo ${var:+nonempty}'
> nonempty

Thanks for the report! I forgot to discard the result of the unused
expansion.

---8<---
Subject: expand: Discard result of unused expansion in evalvar

The commit 3cd538634f71538370f5af239f342aec48b7470b broke parameter
expansion where the nested expanded word needs to be discarded.
This is because the EXP_DISCARD flag wasn't set where it should
have been:

        $ src/dash -c 'var=; echo ${var:+nonempty}'
        nonempty

This patch fixes it by setting it where needed.

Reported-by: Martijn Dekker <[email protected]>
Fixes: 3cd538634f71 ("expand: Do not reprocess data when...")
Signed-off-by: Herbert Xu <[email protected]>

diff --git a/src/expand.c b/src/expand.c
index 14daa63..e890052 100644
--- a/src/expand.c
+++ b/src/expand.c
@@ -698,6 +698,7 @@ evalvar(char *p, int flag)
        int patloc;
        int startloc;
        ssize_t varlen;
+       int discard;
        int quoted;
 
        varflags = *p++;
@@ -713,21 +714,24 @@ again:
        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)
+               p = argstr(p, flag | EXP_TILDE | EXP_WORD |
+                             (discard ^ EXP_DISCARD));
+               if (discard)
                        return p;
                goto record;
 
        case VSASSIGN:
        case VSQUESTION:
-               if (varlen >= 0)
+               if (!discard)
                        goto record;
 
                p = subevalvar(p, var, 0, startloc, varflags,
@@ -740,7 +744,7 @@ again:
                goto again;
        }
 
-       if (varlen < 0 && uflag)
+       if (discard && uflag)
                varunset(p, var, 0, 0);
 
        if (subtype == VSLENGTH) {
@@ -765,7 +769,7 @@ again:
        }
 #endif
 
-       flag |= varlen < 0 ? EXP_DISCARD : 0;
+       flag |= discard;
        if (!(flag & EXP_DISCARD)) {
                /*
                 * Terminate the string and start recording the pattern
-- 
Email: Herbert Xu <[email protected]>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

Reply via email to