Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: bug in parameter expansion



On Wed, 7 Nov 2012 14:13:36 -0500 (EST)
Scott Moser <smoser@xxxxxxxxxx> wrote:
> This issue was initially reported against shell code delivered in
> cloud-init at [1], but it seems to me to be a bug in zsh's posix shell
> behavior.

As it happens, that's not quite true, because zsh doesn't have POSIX
behaviour by default, and it will work as you expect if you invoke it as
sh or "setopt noequals".

It's still pretty funny, even in the native mode, though.  That's a very
strange place for =-expansion to happen.

It's happening because we look at the string "=*" and we tokenise that to
make patterns (such as the "*") active if it was in quotes.  We tokenise
the "=" the same as if it were a command line argument.  I can't think
of any occasion we'd want to do that if we know it's *not* a command
line argument: there's already a flag for this, so the fix is simple.
Maybe someone can think of a pathological case where we should do the
=-expansion (or =(...) expansion) even in a substituted string, but
I can't think of one.  This doesn't trigger any test failures.

Index: Src/lex.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/lex.c,v
retrieving revision 1.73
diff -p -u -r1.73 lex.c
--- Src/lex.c	5 Oct 2012 21:35:06 -0000	1.73
+++ Src/lex.c	7 Nov 2012 20:37:05 -0000
@@ -1265,51 +1265,53 @@ gettokstr(int c, int sub)
 		break;
 	    goto brk;
 	case LX2_EQUALS:
-	    if (intpos) {
-		e = hgetc();
-		if (e != '(') {
-		    hungetc(e);
-		    lexstop = 0;
-		    c = Equals;
-		} else {
-		    add(Equals);
-		    if (skipcomm()) {
-			peek = LEXERR;
-			goto brk;
-		    }
-		    c = Outpar;
-		}
-	    } else if (!sub && peek != ENVSTRING &&
-		       incmdpos && !bct && !brct) {
-		char *t = tokstr;
-		if (idigit(*t))
-		    while (++t < bptr && idigit(*t));
-		else {
-		    int sav = *bptr;
-		    *bptr = '\0';
-		    t = itype_end(t, IIDENT, 0);
-		    if (t < bptr) {
-			skipparens(Inbrack, Outbrack, &t);
+	    if (!sub) {
+		if (intpos) {
+		    e = hgetc();
+		    if (e != '(') {
+			hungetc(e);
+			lexstop = 0;
+			c = Equals;
 		    } else {
-			*bptr = sav;
+			add(Equals);
+			if (skipcomm()) {
+			    peek = LEXERR;
+			    goto brk;
+			}
+			c = Outpar;
 		    }
-		}
-		if (*t == '+')
-                    t++;
-		if (t == bptr) {
-		    e = hgetc();
-		    if (e == '(' && incmdpos) {
+		} else if (peek != ENVSTRING &&
+			   incmdpos && !bct && !brct) {
+		    char *t = tokstr;
+		    if (idigit(*t))
+			while (++t < bptr && idigit(*t));
+		    else {
+			int sav = *bptr;
 			*bptr = '\0';
-			return ENVARRAY;
+			t = itype_end(t, IIDENT, 0);
+			if (t < bptr) {
+			    skipparens(Inbrack, Outbrack, &t);
+			} else {
+			    *bptr = sav;
+			}
 		    }
-		    hungetc(e);
-		    lexstop = 0;
-		    peek = ENVSTRING;
-		    intpos = 2;
+		    if (*t == '+')
+			t++;
+		    if (t == bptr) {
+			e = hgetc();
+			if (e == '(' && incmdpos) {
+			    *bptr = '\0';
+			    return ENVARRAY;
+			}
+			hungetc(e);
+			lexstop = 0;
+			peek = ENVSTRING;
+			intpos = 2;
+		    } else
+			c = Equals;
 		} else
 		    c = Equals;
-	    } else
-		c = Equals;
+	    }
 	    break;
 	case LX2_BKSLASH:
 	    c = hgetc();

-- 
Peter Stephenson <p.w.stephenson@xxxxxxxxxxxx>
Web page now at http://homepage.ntlworld.com/p.w.stephenson/



Messages sorted by: Reverse Date, Date, Thread, Author