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