On Sun, Mar 04, 2018 at 12:44:59PM +0100, Harald van Dijk wrote:
>
> command:      set -- a ""; space=" "; printf "<%s>" "$@"$space
> bash:         <a><>
> dash 0.5.8:   <a>< >
> dash 0.5.9.1: <a>< >
> dash patched: <a><>

This is actually composed of two bugs.  First of all our tracking
of quotemark is wrong so anything after "$@" becomes quoted.  Once
we fix that then the problem is that the first space character
after "$@" is not recognised as an IFS.

This patch fixes both.

Signed-off-by: Herbert Xu <herb...@gondor.apana.org.au>

diff --git a/src/expand.c b/src/expand.c
index 705fef7..ce9f982 100644
--- a/src/expand.c
+++ b/src/expand.c
@@ -318,13 +318,13 @@ start:
                case CTLENDVAR: /* ??? */
                        goto breakloop;
                case CTLQUOTEMARK:
-                       inquotes ^= EXP_QUOTED;
                        /* "$@" syntax adherence hack */
-                       if (inquotes && !memcmp(p, dolatstr + 1,
-                                               DOLATSTRLEN - 1)) {
-                               p = evalvar(p + 1, flag | inquotes) + 1;
+                       if (!inquotes && !memcmp(p, dolatstr + 1,
+                                                DOLATSTRLEN - 1)) {
+                               p = evalvar(p + 1, flag | EXP_QUOTED) + 1;
                                goto start;
                        }
+                       inquotes ^= EXP_QUOTED;
 addquote:
                        if (flag & QUOTES_ESC) {
                                p--;
@@ -1032,7 +1032,10 @@ ifsbreakup(char *string, int maxargs, struct arglist 
*arglist)
                realifs = ifsset() ? ifsval() : defifs;
                ifsp = &ifsfirst;
                do {
+                       int afternul;
+
                        p = string + ifsp->begoff;
+                       afternul = nulonly;
                        nulonly = ifsp->nulonly;
                        ifs = nulonly ? nullstr : realifs;
                        ifsspc = 0;
@@ -1097,7 +1100,7 @@ ifsbreakup(char *string, int maxargs, struct arglist 
*arglist)
                                }
 
                                if (isifs) {
-                                       if (!nulonly)
+                                       if (!(afternul || nulonly))
                                                ifsspc = isdefifs;
                                        /* Ignore IFS whitespace at start */
                                        if (q == start && ifsspc) {
-- 
Email: Herbert Xu <herb...@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
--
To unsubscribe from this list: send the line "unsubscribe dash" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to