ash: expand: Fix bugs with words connected to the right of $@
authorDenys Vlasenko <vda.linux@googlemail.com>
Mon, 2 Apr 2018 12:27:50 +0000 (14:27 +0200)
committerDenys Vlasenko <vda.linux@googlemail.com>
Mon, 2 Apr 2018 12:27:50 +0000 (14:27 +0200)
Upstream email:

    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 <herbert@gondor.apana.org.au>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
shell/ash.c
shell/ash_test/ash-parsing/starquoted3.right [new file with mode: 0644]
shell/ash_test/ash-parsing/starquoted3.tests [new file with mode: 0755]
shell/hush_test/hush-parsing/starquoted3.right [new file with mode: 0644]
shell/hush_test/hush-parsing/starquoted3.tests [new file with mode: 0755]

index 35ea58f3aa361976cce76a7dadd0742db5dbb3dc..d82eba15f7b0018fc8aef52528c9ea10cbc30681 100644 (file)
@@ -5975,7 +5975,10 @@ ifsbreakup(char *string, 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;
@@ -5987,7 +5990,7 @@ ifsbreakup(char *string, struct arglist *arglist)
                                        p++;
                                        continue;
                                }
-                               if (!nulonly)
+                               if (!(afternul || nulonly))
                                        ifsspc = (strchr(defifs, *p) != NULL);
                                /* Ignore IFS whitespace at start */
                                if (q == start && ifsspc) {
@@ -6650,12 +6653,12 @@ argstr(char *p, int flags)
                case CTLENDVAR: /* ??? */
                        goto breakloop;
                case CTLQUOTEMARK:
-                       inquotes ^= EXP_QUOTED;
                        /* "$@" syntax adherence hack */
-                       if (inquotes && !memcmp(p, dolatstr + 1, DOLATSTRLEN - 1)) {
-                               p = evalvar(p + 1, flags | inquotes) + 1;
+                       if (!inquotes && !memcmp(p, dolatstr + 1, DOLATSTRLEN - 1)) {
+                               p = evalvar(p + 1, flags | EXP_QUOTED) + 1;
                                goto start;
                        }
+                       inquotes ^= EXP_QUOTED;
  addquote:
                        if (flags & QUOTES_ESC) {
                                p--;
diff --git a/shell/ash_test/ash-parsing/starquoted3.right b/shell/ash_test/ash-parsing/starquoted3.right
new file mode 100644 (file)
index 0000000..fea246c
--- /dev/null
@@ -0,0 +1,2 @@
+<a>
+<>
diff --git a/shell/ash_test/ash-parsing/starquoted3.tests b/shell/ash_test/ash-parsing/starquoted3.tests
new file mode 100755 (executable)
index 0000000..8eefe42
--- /dev/null
@@ -0,0 +1 @@
+set -- a ""; space=" "; printf "<%s>\n" "$@"$space
diff --git a/shell/hush_test/hush-parsing/starquoted3.right b/shell/hush_test/hush-parsing/starquoted3.right
new file mode 100644 (file)
index 0000000..fea246c
--- /dev/null
@@ -0,0 +1,2 @@
+<a>
+<>
diff --git a/shell/hush_test/hush-parsing/starquoted3.tests b/shell/hush_test/hush-parsing/starquoted3.tests
new file mode 100755 (executable)
index 0000000..8eefe42
--- /dev/null
@@ -0,0 +1 @@
+set -- a ""; space=" "; printf "<%s>\n" "$@"$space