Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/usr.bin/make make: prevent newline injection in .for loops
details: https://anonhg.NetBSD.org/src/rev/94772353195c
branches: trunk
changeset: 379894:94772353195c
user: rillig <rillig%NetBSD.org@localhost>
date: Fri Jun 25 16:10:07 2021 +0000
description:
make: prevent newline injection in .for loops
When a value of a .for loop contained a literal newline, such as from
the expression ${.newline}, that newline was passed verbatim to the
"expanded current body" of the .for loop. There it was interpreted as a
literal newline, which ended the current line and started a new one.
This resulted in several syntax errors.
In cases like these, print a more precise error message.
diffstat:
usr.bin/make/for.c | 11 ++++++++---
usr.bin/make/unit-tests/directive-for-escape.exp | 16 ++++++----------
usr.bin/make/unit-tests/directive-for-escape.mk | 8 +++++---
3 files changed, 19 insertions(+), 16 deletions(-)
diffs (88 lines):
diff -r 469caab55a91 -r 94772353195c usr.bin/make/for.c
--- a/usr.bin/make/for.c Fri Jun 25 15:56:02 2021 +0000
+++ b/usr.bin/make/for.c Fri Jun 25 16:10:07 2021 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: for.c,v 1.143 2021/06/24 23:19:52 rillig Exp $ */
+/* $NetBSD: for.c,v 1.144 2021/06/25 16:10:07 rillig Exp $ */
/*
* Copyright (c) 1992, The Regents of the University of California.
@@ -58,7 +58,7 @@
#include "make.h"
/* "@(#)for.c 8.1 (Berkeley) 6/6/93" */
-MAKE_RCSID("$NetBSD: for.c,v 1.143 2021/06/24 23:19:52 rillig Exp $");
+MAKE_RCSID("$NetBSD: for.c,v 1.144 2021/06/25 16:10:07 rillig Exp $");
/* One of the variables to the left of the "in" in a .for loop. */
@@ -325,7 +325,8 @@ NeedsEscapes(const char *value, char end
const char *p;
for (p = value; *p != '\0'; p++) {
- if (*p == ':' || *p == '$' || *p == '\\' || *p == endc)
+ if (*p == ':' || *p == '$' || *p == '\\' || *p == endc ||
+ *p == '\n')
return true;
}
return false;
@@ -360,6 +361,10 @@ Buf_AddEscaped(Buffer *cmds, const char
Buf_AddByte(cmds, '\\');
} else if (ch == ':' || ch == '\\' || ch == endc)
Buf_AddByte(cmds, '\\');
+ else if (ch == '\n') {
+ Parse_Error(PARSE_FATAL, "newline in .for value");
+ ch = ' '; /* prevent newline injection */
+ }
Buf_AddByte(cmds, ch);
}
}
diff -r 469caab55a91 -r 94772353195c usr.bin/make/unit-tests/directive-for-escape.exp
--- a/usr.bin/make/unit-tests/directive-for-escape.exp Fri Jun 25 15:56:02 2021 +0000
+++ b/usr.bin/make/unit-tests/directive-for-escape.exp Fri Jun 25 16:10:07 2021 +0000
@@ -80,17 +80,13 @@ make: "directive-for-escape.mk" line 118
make: "directive-for-escape.mk" line 119: eight dollardollardollardollar and no cents.
make: "directive-for-escape.mk" line 128: eight and no cents.
For: end for 1
+make: "directive-for-escape.mk" line 135: newline in .for value
+make: "directive-for-escape.mk" line 135: newline in .for value
For: loop body:
-. info short: ${:U"
-"}
-. info long: ${:U"
-"}
-make: Unclosed variable expression, expecting '}' for modifier "U"" of variable "" with value """
-make: "directive-for-escape.mk" line 134: short: "
-make: "directive-for-escape.mk" line 135: Invalid line type
-make: Unclosed variable expression, expecting '}' for modifier "U"" of variable "" with value """
-make: "directive-for-escape.mk" line 136: long: "
-make: "directive-for-escape.mk" line 137: Invalid line type
+. info short: ${:U" "}
+. info long: ${:U" "}
+make: "directive-for-escape.mk" line 136: short: " "
+make: "directive-for-escape.mk" line 137: long: " "
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1
diff -r 469caab55a91 -r 94772353195c usr.bin/make/unit-tests/directive-for-escape.mk
--- a/usr.bin/make/unit-tests/directive-for-escape.mk Fri Jun 25 15:56:02 2021 +0000
+++ b/usr.bin/make/unit-tests/directive-for-escape.mk Fri Jun 25 16:10:07 2021 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: directive-for-escape.mk,v 1.9 2021/06/25 15:56:02 rillig Exp $
+# $NetBSD: directive-for-escape.mk,v 1.10 2021/06/25 16:10:07 rillig Exp $
#
# Test escaping of special characters in the iteration values of a .for loop.
# These values get expanded later using the :U variable modifier, and this
@@ -128,8 +128,10 @@ closing-brace= } # guard against an
.info eight ${$}${$}${$}${$} and no cents.
# What happens if the values from the .for loop contain a literal newline?
-# Oops, the newline is added verbatim to the loop body, where it is later
-# interpreted as an ordinary newline.
+# Before for.c 1.144 from 2021-06-25, the newline was passed verbatim to the
+# body of the .for loop, where it was then interpreted as a literal newline,
+# leading to syntax errors such as "Unclosed variable expression" in the upper
+# line and "Invalid line type" in the lower line.
.for i in "${.newline}"
. info short: $i
. info long: ${i}
Home |
Main Index |
Thread Index |
Old Index