Module Name:    src
Committed By:   rillig
Date:           Mon Nov  2 22:44:29 UTC 2020

Modified Files:
        src/usr.bin/make: parse.c
        src/usr.bin/make/unit-tests: varname.exp varname.mk

Log Message:
make(1): document undefined behavior in Parse_IsVar

Sigh.  If only C could be compiled in strict mode that detects these
out-of-bounds memory accesses.


To generate a diff of this commit:
cvs rdiff -u -r1.420 -r1.421 src/usr.bin/make/parse.c
cvs rdiff -u -r1.5 -r1.6 src/usr.bin/make/unit-tests/varname.exp
cvs rdiff -u -r1.6 -r1.7 src/usr.bin/make/unit-tests/varname.mk

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/parse.c
diff -u src/usr.bin/make/parse.c:1.420 src/usr.bin/make/parse.c:1.421
--- src/usr.bin/make/parse.c:1.420	Sun Nov  1 00:24:57 2020
+++ src/usr.bin/make/parse.c	Mon Nov  2 22:44:29 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: parse.c,v 1.420 2020/11/01 00:24:57 rillig Exp $	*/
+/*	$NetBSD: parse.c,v 1.421 2020/11/02 22:44:29 rillig Exp $	*/
 
 /*
  * Copyright (c) 1988, 1989, 1990, 1993
@@ -117,7 +117,7 @@
 #include "pathnames.h"
 
 /*	"@(#)parse.c	8.3 (Berkeley) 3/19/94"	*/
-MAKE_RCSID("$NetBSD: parse.c,v 1.420 2020/11/01 00:24:57 rillig Exp $");
+MAKE_RCSID("$NetBSD: parse.c,v 1.421 2020/11/02 22:44:29 rillig Exp $");
 
 /* types and constants */
 
@@ -1850,6 +1850,8 @@ Parse_IsVar(const char *p, VarAssign *ou
 #endif
 
     /* Scan for one of the assignment operators outside a variable expansion */
+    /* FIXME: undefined behavior. In unit-tests/varname.mk:try1, at the end
+     * of the loop, p already points to the next line. */
     while ((ch = *p++) != 0) {
 	if (ch == '(' || ch == '{') {
 	    level++;

Index: src/usr.bin/make/unit-tests/varname.exp
diff -u src/usr.bin/make/unit-tests/varname.exp:1.5 src/usr.bin/make/unit-tests/varname.exp:1.6
--- src/usr.bin/make/unit-tests/varname.exp:1.5	Mon Nov  2 22:29:48 2020
+++ src/usr.bin/make/unit-tests/varname.exp	Mon Nov  2 22:44:29 2020
@@ -9,16 +9,16 @@ Applying ${:U...} to "" (VARE_UNDEFERR|V
 Result of ${:UVAR(((} is "VAR(((" (VARE_UNDEFERR|VARE_WANTRES, none, VEF_UNDEF|VEF_DEF)
 Global:.ALLTARGETS =  VAR(((=)
 No closing parenthesis in archive specification
-make: "varname.mk" line 26: Error in archive specification: "VAR"
+make: "varname.mk" line 29: Error in archive specification: "VAR"
 Var_Parse: ${:UVAR\(\(\(}=	try2 with VARE_UNDEFERR|VARE_WANTRES
 Applying ${:U...} to "" (VARE_UNDEFERR|VARE_WANTRES, none, VEF_UNDEF)
 Result of ${:UVAR\(\(\(} is "VAR\(\(\(" (VARE_UNDEFERR|VARE_WANTRES, none, VEF_UNDEF|VEF_DEF)
 Global:.ALLTARGETS =  VAR(((=) VAR\(\(\(=
-make: "varname.mk" line 27: Need an operator
+make: "varname.mk" line 30: Need an operator
 Var_Parse: ${:UVAR\(\(\(}=	try3 with VARE_UNDEFERR|VARE_WANTRES
 Applying ${:U...} to "" (VARE_UNDEFERR|VARE_WANTRES, none, VEF_UNDEF)
 Result of ${:UVAR\(\(\(} is "VAR\(\(\(" (VARE_UNDEFERR|VARE_WANTRES, none, VEF_UNDEF|VEF_DEF)
-make: "varname.mk" line 28: Need an operator
+make: "varname.mk" line 31: Need an operator
 Global:.MAKEFLAGS =  -r -k -d v -d
 Global:.MAKEFLAGS =  -r -k -d v -d 0
 make: Fatal errors encountered -- cannot continue

Index: src/usr.bin/make/unit-tests/varname.mk
diff -u src/usr.bin/make/unit-tests/varname.mk:1.6 src/usr.bin/make/unit-tests/varname.mk:1.7
--- src/usr.bin/make/unit-tests/varname.mk:1.6	Mon Nov  2 22:29:48 2020
+++ src/usr.bin/make/unit-tests/varname.mk	Mon Nov  2 22:44:29 2020
@@ -1,4 +1,4 @@
-# $NetBSD: varname.mk,v 1.6 2020/11/02 22:29:48 rillig Exp $
+# $NetBSD: varname.mk,v 1.7 2020/11/02 22:44:29 rillig Exp $
 #
 # Tests for special variables, such as .MAKE or .PARSEDIR.
 # And for variable names in general.
@@ -23,6 +23,10 @@ ${VARNAME}=	3 open parentheses
 
 # In the above test, the variable name is constructed indirectly.  Neither
 # of the following expressions produces the intended effect.
+#
+# This is not a variable assignment since the parentheses and braces are not
+# balanced.  At the end of the line, there are still 3 levels open, which
+# means the variable name is not finished.
 ${:UVAR(((}=	try1
 ${:UVAR\(\(\(}=	try2
 ${:UVAR\(\(\(}=	try3

Reply via email to