summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Smith <psmith@gnu.org>2023-01-03 02:14:24 -0500
committerPaul Smith <psmith@gnu.org>2023-01-03 02:14:24 -0500
commit5ae02ff8c10e611aca7d5c6f60d3461aa0746694 (patch)
treed303732dc24ff23150a400172cbfb132e31afba3
parent1ceeb8c64bf2a95bdfc5e5bd221886c6df74f560 (diff)
downloadmake-git-5ae02ff8c10e611aca7d5c6f60d3461aa0746694.tar.gz
[SV 63609] Avoid buffer overrun in --warn-undefined-variables
Reported by Dmitry Goncharov <dgoncharov@users.sf.net> * src/variable.c (struct defined_vars): Create a struct that holds the name and length of each variable name. (warn_undefined): Check the lengths before comparing the contents. * tests/scripts/options/warn-undefined-variables: Add a test.
-rw-r--r--src/variable.c30
-rw-r--r--tests/scripts/options/warn-undefined-variables11
2 files changed, 33 insertions, 8 deletions
diff --git a/src/variable.c b/src/variable.c
index a0299639..009ee540 100644
--- a/src/variable.c
+++ b/src/variable.c
@@ -1793,20 +1793,34 @@ try_variable_definition (const floc *flocp, const char *line,
/* These variables are internal to make, and so considered "defined" for the
purposes of warn_undefined even if they are not really defined. */
-static const char *const defined_vars[] = {
- "MAKECMDGOALS", "MAKE_RESTARTS", "MAKE_TERMOUT", "MAKE_TERMERR",
- "MAKEOVERRIDES", ".DEFAULT", "-*-command-variables-*-", "-*-eval-flags-*-",
- "VPATH", "GPATH",
- NULL };
+struct defined_vars
+ {
+ const char *name;
+ size_t len;
+ };
+
+static const struct defined_vars defined_vars[] = {
+ { STRING_SIZE_TUPLE ("MAKECMDGOALS") },
+ { STRING_SIZE_TUPLE ("MAKE_RESTARTS") },
+ { STRING_SIZE_TUPLE ("MAKE_TERMOUT") },
+ { STRING_SIZE_TUPLE ("MAKE_TERMERR") },
+ { STRING_SIZE_TUPLE ("MAKEOVERRIDES") },
+ { STRING_SIZE_TUPLE (".DEFAULT") },
+ { STRING_SIZE_TUPLE ("-*-command-variables-*-") },
+ { STRING_SIZE_TUPLE ("-*-eval-flags-*-") },
+ { STRING_SIZE_TUPLE ("VPATH") },
+ { STRING_SIZE_TUPLE ("GPATH") },
+ { NULL, 0 }
+};
void
warn_undefined (const char *name, size_t len)
{
if (warn_undefined_variables_flag)
{
- const char *const *cp;
- for (cp = defined_vars; *cp != NULL; ++cp)
- if (memcmp (*cp, name, len) == 0 && (*cp)[len] == '\0')
+ const struct defined_vars *dp;
+ for (dp = defined_vars; dp->name != NULL; ++dp)
+ if (dp->len == len && memcmp (dp->name, name, len) == 0)
return;
error (reading_file, len, _("warning: undefined variable '%.*s'"),
diff --git a/tests/scripts/options/warn-undefined-variables b/tests/scripts/options/warn-undefined-variables
index 9bd40865..d9653d2c 100644
--- a/tests/scripts/options/warn-undefined-variables
+++ b/tests/scripts/options/warn-undefined-variables
@@ -35,4 +35,15 @@ run_make_test(undef, '--warn-undefined-variables',
#MAKEFILE#:9: warning: undefined variable 'UNDEFINED'
ref");
+# sv 63609.
+# Test for buffer overrun in warn_undefined.
+run_make_test(q!
+all:;
+X := $(averyveryverylongvariablename)
+!,
+ '--warn-undefined-variables',
+ "#MAKEFILE#:3: warning: undefined variable 'averyveryverylongvariablename'
+#MAKE#: 'all' is up to date.\n"
+);
+
1;