Module Name:    src
Committed By:   sjg
Date:           Mon May 19 22:09:58 UTC 2014

Modified Files:
        src/usr.bin/make: var.c

Log Message:
Var_Parse: endc only counts when at the correct nesting depth.
This ensures we correctly detect errors like:
.if empty(VAR && !empty(FOO)

Var_Subst: if Var_Parse returns var_Error it is an error.
This ensures we detect errors like:

VAR:= ${FOO.${GOO}


To generate a diff of this commit:
cvs rdiff -u -r1.184 -r1.185 src/usr.bin/make/var.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/usr.bin/make/var.c
diff -u src/usr.bin/make/var.c:1.184 src/usr.bin/make/var.c:1.185
--- src/usr.bin/make/var.c:1.184	Wed Sep  4 15:38:26 2013
+++ src/usr.bin/make/var.c	Mon May 19 22:09:58 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: var.c,v 1.184 2013/09/04 15:38:26 sjg Exp $	*/
+/*	$NetBSD: var.c,v 1.185 2014/05/19 22:09:58 sjg Exp $	*/
 
 /*
  * Copyright (c) 1988, 1989, 1990, 1993
@@ -69,14 +69,14 @@
  */
 
 #ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: var.c,v 1.184 2013/09/04 15:38:26 sjg Exp $";
+static char rcsid[] = "$NetBSD: var.c,v 1.185 2014/05/19 22:09:58 sjg Exp $";
 #else
 #include <sys/cdefs.h>
 #ifndef lint
 #if 0
 static char sccsid[] = "@(#)var.c	8.3 (Berkeley) 3/19/94";
 #else
-__RCSID("$NetBSD: var.c,v 1.184 2013/09/04 15:38:26 sjg Exp $");
+__RCSID("$NetBSD: var.c,v 1.185 2014/05/19 22:09:58 sjg Exp $");
 #endif
 #endif /* not lint */
 #endif
@@ -3660,6 +3660,7 @@ Var_Parse(const char *str, GNode *ctxt, 
 	}
     } else {
 	Buffer buf;	/* Holds the variable name */
+	int depth = 1;
 
 	endc = startc == PROPEN ? PRCLOSE : BRCLOSE;
 	Buf_Init(&buf, 0);
@@ -3667,11 +3668,22 @@ Var_Parse(const char *str, GNode *ctxt, 
 	/*
 	 * Skip to the end character or a colon, whichever comes first.
 	 */
-	for (tstr = str + 2;
-	     *tstr != '\0' && *tstr != endc && *tstr != ':';
-	     tstr++)
+	for (tstr = str + 2; *tstr != '\0'; tstr++)
 	{
 	    /*
+	     * Track depth so we can spot parse errors.
+	     */
+	    if (*tstr == startc) {
+		depth++;
+	    }
+	    if (*tstr == endc) {
+		if (--depth == 0)
+		    break;
+	    }
+	    if (depth == 1 && *tstr == ':') {
+		break;
+	    }
+	    /*
 	     * A variable inside a variable, expand
 	     */
 	    if (*tstr == '$') {
@@ -3690,7 +3702,7 @@ Var_Parse(const char *str, GNode *ctxt, 
 	}
 	if (*tstr == ':') {
 	    haveModifier = TRUE;
-	} else if (*tstr != '\0') {
+	} else if (*tstr == endc) {
 	    haveModifier = FALSE;
 	} else {
 	    /*
@@ -4040,7 +4052,7 @@ Var_Subst(const char *var, const char *s
 		 */
 		if (oldVars) {
 		    str += length;
-		} else if (undefErr) {
+		} else if (undefErr || val == var_Error) {
 		    /*
 		     * If variable is undefined, complain and skip the
 		     * variable. The complaint will stop us from doing anything

Reply via email to