Module Name: src Committed By: rillig Date: Sat Dec 19 22:10:18 UTC 2020
Modified Files: src/usr.bin/make: var.c src/usr.bin/make/unit-tests: directive-undef.exp directive-undef.mk Log Message: make(1): error out if .undef has not exactly 1 argument To generate a diff of this commit: cvs rdiff -u -r1.736 -r1.737 src/usr.bin/make/var.c cvs rdiff -u -r1.3 -r1.4 src/usr.bin/make/unit-tests/directive-undef.exp cvs rdiff -u -r1.7 -r1.8 src/usr.bin/make/unit-tests/directive-undef.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/var.c diff -u src/usr.bin/make/var.c:1.736 src/usr.bin/make/var.c:1.737 --- src/usr.bin/make/var.c:1.736 Sat Dec 19 20:47:24 2020 +++ src/usr.bin/make/var.c Sat Dec 19 22:10:17 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: var.c,v 1.736 2020/12/19 20:47:24 rillig Exp $ */ +/* $NetBSD: var.c,v 1.737 2020/12/19 22:10:17 rillig Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -131,7 +131,7 @@ #include "metachar.h" /* "@(#)var.c 8.3 (Berkeley) 3/19/94" */ -MAKE_RCSID("$NetBSD: var.c,v 1.736 2020/12/19 20:47:24 rillig Exp $"); +MAKE_RCSID("$NetBSD: var.c,v 1.737 2020/12/19 22:10:17 rillig Exp $"); /* A string that may need to be freed after use. */ typedef struct FStr { @@ -531,18 +531,39 @@ Var_Delete(const char *name, GNode *ctxt Var_DeleteVar(name, ctxt); } +/* + * Undefine a single variable from the global scope. The argument is + * expanded once. + */ void Var_Undef(char *arg) { + /* + * The argument must consist of exactly 1 word. Accepting more than + * 1 word would have required to split the argument into several + * words, and such splitting is already done subtly different in many + * other places of make. + * + * Using Str_Words to split the words, followed by Var_Subst to expand + * each variable name once would make it impossible to undefine + * variables whose names contain space characters or unbalanced + * quotes or backslashes in arbitrary positions. + * + * Using Var_Subst on the whole argument and splitting the words + * afterwards using Str_Words would make it impossible to undefine + * variables whose names contain space characters. + */ char *cp = arg; for (; !ch_isspace(*cp) && *cp != '\0'; cp++) continue; + if (cp == arg || *cp != '\0') { + Parse_Error(PARSE_FATAL, + "The .undef directive requires exactly 1 argument"); + } *cp = '\0'; Var_Delete(arg, VAR_GLOBAL); - /* TODO: undefine all variables, not only the first */ - /* TODO: use Str_Words, like everywhere else */ } static Boolean Index: src/usr.bin/make/unit-tests/directive-undef.exp diff -u src/usr.bin/make/unit-tests/directive-undef.exp:1.3 src/usr.bin/make/unit-tests/directive-undef.exp:1.4 --- src/usr.bin/make/unit-tests/directive-undef.exp:1.3 Sun Dec 13 01:07:54 2020 +++ src/usr.bin/make/unit-tests/directive-undef.exp Sat Dec 19 22:10:18 2020 @@ -1 +1,5 @@ -exit status 0 +make: "directive-undef.mk" line 14: The .undef directive requires exactly 1 argument +make: "directive-undef.mk" line 24: The .undef directive requires exactly 1 argument +make: Fatal errors encountered -- cannot continue +make: stopped in unit-tests +exit status 1 Index: src/usr.bin/make/unit-tests/directive-undef.mk diff -u src/usr.bin/make/unit-tests/directive-undef.mk:1.7 src/usr.bin/make/unit-tests/directive-undef.mk:1.8 --- src/usr.bin/make/unit-tests/directive-undef.mk:1.7 Sat Dec 19 20:35:39 2020 +++ src/usr.bin/make/unit-tests/directive-undef.mk Sat Dec 19 22:10:18 2020 @@ -1,4 +1,4 @@ -# $NetBSD: directive-undef.mk,v 1.7 2020/12/19 20:35:39 rillig Exp $ +# $NetBSD: directive-undef.mk,v 1.8 2020/12/19 22:10:18 rillig Exp $ # # Tests for the .undef directive. # @@ -16,9 +16,39 @@ . warning $1$2$3 .endif -# Without any arguments, .undef tries to delete the variable with the empty -# name, which never exists; see varname-empty.mk. -.undef # oops: missing argument + +# Without any arguments, until var.c 1.736 from 2020-12-19, .undef tried +# to delete the variable with the empty name, which never exists; see +# varname-empty.mk. Since var.c 1.737 from 2020-12-19, .undef complains +# about a missing argument. +.undef + + +# Trying to delete the variable with the empty name is ok, it just won't +# ever do anything since that variable is never defined. +.undef ${:U} + + +# The argument of .undef is a single word, delimited by whitespace, without +# any possibility of escaping or having variable expressions containing +# spaces. This word is then expanded exactly once, and the expanded string +# is the single variable name. This allows variable names to contain spaces, +# as well as unbalanced single and double quotes. +1= 1 +2= 2 +3= 3 +${:U1 2 3}= one two three +VARNAMES= 1 2 3 +.undef ${VARNAMES} # undefines the variable "1 2 3" +.if defined(${:U1 2 3}) +. error +.endif +.if ${1}${2}${3} != "123" # these are still defined +. error +.endif +.undef 1 +.undef 2 +.undef 3 # It must be possible to undefine variables whose name includes spaces.