summaryrefslogtreecommitdiff
path: root/usr.bin/make
diff options
context:
space:
mode:
authorrillig <rillig@NetBSD.org>2020-12-12 19:31:17 +0000
committerrillig <rillig@NetBSD.org>2020-12-12 19:31:17 +0000
commitd67ddbdbbfb307bef8dfe6d77245b51b27b57193 (patch)
treeb37bd77c2c5ce03de5d02bc239860b49217eef42 /usr.bin/make
parent2f32b0fe560a6626de78de2ad9abd935ad30b397 (diff)
make(1): extract ExportVars from Var_Export
Diffstat (limited to 'usr.bin/make')
-rw-r--r--usr.bin/make/unit-tests/directive-export.exp2
-rw-r--r--usr.bin/make/unit-tests/directive-export.mk6
-rw-r--r--usr.bin/make/var.c50
3 files changed, 34 insertions, 24 deletions
diff --git a/usr.bin/make/unit-tests/directive-export.exp b/usr.bin/make/unit-tests/directive-export.exp
index bd828b63c10..c1ba0261889 100644
--- a/usr.bin/make/unit-tests/directive-export.exp
+++ b/usr.bin/make/unit-tests/directive-export.exp
@@ -1,4 +1,4 @@
-make: "directive-export.mk" line 25: Unknown directive "expor"
+make: "directive-export.mk" line 29: Unknown directive "expor"
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1
diff --git a/usr.bin/make/unit-tests/directive-export.mk b/usr.bin/make/unit-tests/directive-export.mk
index bae50aecbda..e6c1674b67d 100644
--- a/usr.bin/make/unit-tests/directive-export.mk
+++ b/usr.bin/make/unit-tests/directive-export.mk
@@ -1,4 +1,4 @@
-# $NetBSD: directive-export.mk,v 1.4 2020/11/03 17:17:31 rillig Exp $
+# $NetBSD: directive-export.mk,v 1.5 2020/12/12 19:31:18 rillig Exp $
#
# Tests for the .export directive.
@@ -7,6 +7,10 @@
INDIRECT= indirect
VAR= value $$ ${INDIRECT}
+# Before 2020-12-13, this unusual expression invoked undefined behavior since
+# it accessed out-of-bounds memory via Var_Export -> ExportVar -> MayExport.
+.export ${:U }
+
# A variable is exported using the .export directive.
# During that, its value is expanded, just like almost everywhere else.
.export VAR
diff --git a/usr.bin/make/var.c b/usr.bin/make/var.c
index 00d33defca8..7c585161562 100644
--- a/usr.bin/make/var.c
+++ b/usr.bin/make/var.c
@@ -1,4 +1,4 @@
-/* $NetBSD: var.c,v 1.725 2020/12/12 18:53:53 rillig Exp $ */
+/* $NetBSD: var.c,v 1.726 2020/12/12 19:31: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.725 2020/12/12 18:53:53 rillig Exp $");
+MAKE_RCSID("$NetBSD: var.c,v 1.726 2020/12/12 19:31:17 rillig Exp $");
/* A string that may need to be freed after use. */
typedef struct FStr {
@@ -671,6 +671,28 @@ Var_ReexportVars(void)
free(val);
}
+static void
+ExportVars(const char *varnames, Boolean isExport, VarExportFlags flags)
+{
+ if (varnames[0] != '\0') {
+ Words words = Str_Words(varnames, FALSE);
+
+ size_t i;
+ for (i = 0; i < words.len; i++) {
+ const char *name = words.words[i];
+ if (ExportVar(name, flags)) {
+ if (var_exportedVars == VAR_EXPORTED_NONE)
+ var_exportedVars = VAR_EXPORTED_SOME;
+ if (isExport && (flags & VAR_EXPORT_PARENT)) {
+ Var_Append(MAKE_EXPORTED, name,
+ VAR_GLOBAL);
+ }
+ }
+ }
+ Words_Free(words);
+ }
+}
+
/*
* This is called when .export is seen or .MAKE.EXPORTED is modified.
*
@@ -683,7 +705,7 @@ void
Var_Export(const char *str, Boolean isExport)
{
VarExportFlags flags;
- char *val;
+ char *varnames;
if (isExport && str[0] == '\0') {
var_exportedVars = VAR_EXPORTED_ALL; /* use with caution! */
@@ -700,26 +722,10 @@ Var_Export(const char *str, Boolean isExport)
flags = VAR_EXPORT_PARENT;
}
- (void)Var_Subst(str, VAR_GLOBAL, VARE_WANTRES, &val);
+ (void)Var_Subst(str, VAR_GLOBAL, VARE_WANTRES, &varnames);
/* TODO: handle errors */
- if (val[0] != '\0') {
- Words words = Str_Words(val, FALSE);
-
- size_t i;
- for (i = 0; i < words.len; i++) {
- const char *name = words.words[i];
- if (ExportVar(name, flags)) {
- if (var_exportedVars == VAR_EXPORTED_NONE)
- var_exportedVars = VAR_EXPORTED_SOME;
- if (isExport && (flags & VAR_EXPORT_PARENT)) {
- Var_Append(MAKE_EXPORTED, name,
- VAR_GLOBAL);
- }
- }
- }
- Words_Free(words);
- }
- free(val);
+ ExportVars(varnames, isExport, flags);
+ free(varnames);
}