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(1): fix out-of-bounds pointer in ParseTrac...
details: https://anonhg.NetBSD.org/src/rev/771a95753eed
branches: trunk
changeset: 945535:771a95753eed
user: rillig <rillig%NetBSD.org@localhost>
date: Sat Oct 31 23:39:01 2020 +0000
description:
make(1): fix out-of-bounds pointer in ParseTrackInput
diffstat:
usr.bin/make/parse.c | 64 +++++++++++++++++++++++++++++++++------------------
1 files changed, 41 insertions(+), 23 deletions(-)
diffs (90 lines):
diff -r 68641aba9a44 -r 771a95753eed usr.bin/make/parse.c
--- a/usr.bin/make/parse.c Sat Oct 31 23:23:22 2020 +0000
+++ b/usr.bin/make/parse.c Sat Oct 31 23:39:01 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: parse.c,v 1.417 2020/10/31 23:10:06 rillig Exp $ */
+/* $NetBSD: parse.c,v 1.418 2020/10/31 23:39:01 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.417 2020/10/31 23:10:06 rillig Exp $");
+MAKE_RCSID("$NetBSD: parse.c,v 1.418 2020/10/31 23:39:01 rillig Exp $");
/* types and constants */
@@ -2351,32 +2351,50 @@
}
}
+static Boolean
+StrContainsWord(const char *str, const char *word)
+{
+ const char *val = str;
+ size_t valLen = strlen(val);
+ size_t wordLen = strlen(word);
+ const char *end;
+
+ if (valLen < wordLen)
+ return FALSE; /* str is too short to contain word */
+
+ end = val + valLen - wordLen;
+ for (; val != NULL; val = strchr(val, ' ')) {
+ if (*val == ' ')
+ val++;
+ if (val > end)
+ return FALSE; /* cannot contain word */
+
+ if (memcmp(val, word, wordLen) == 0 &&
+ (val[wordLen] == '\0' || val[wordLen] == ' '))
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/* XXX: Searching through a set of words with this linear search is
+ * inefficient for variables that contain thousands of words. */
+static Boolean
+VarContainsWord(const char *varname, const char *word)
+{
+ void *val_freeIt;
+ const char *val = Var_Value(varname, VAR_GLOBAL, &val_freeIt);
+ Boolean found = val != NULL && StrContainsWord(val, word);
+ bmake_free(val_freeIt);
+ return found;
+}
+
/* Track the makefiles we read - so makefiles can set dependencies on them.
* Avoid adding anything more than once. */
static void
ParseTrackInput(const char *name)
{
- void *old_freeIt = NULL;
-
- const char *old = Var_Value(MAKE_MAKEFILES, VAR_GLOBAL, &old_freeIt);
- if (old != NULL) {
- size_t name_len = strlen(name);
- /* XXX: undefined behavior if name_len > strlen(old) */
- const char *ep = old + strlen(old) - name_len;
- /* does it contain name? */
- for (; old != NULL; old = strchr(old, ' ')) {
- if (*old == ' ')
- old++;
- if (old > ep)
- break; /* cannot contain name */
- if (memcmp(old, name, name_len) == 0 &&
- (old[name_len] == '\0' || old[name_len] == ' '))
- goto cleanup;
- }
- }
- Var_Append(MAKE_MAKEFILES, name, VAR_GLOBAL);
-cleanup:
- bmake_free(old_freeIt);
+ if (!VarContainsWord(MAKE_MAKEFILES, name))
+ Var_Append(MAKE_MAKEFILES, name, VAR_GLOBAL);
}
Home |
Main Index |
Thread Index |
Old Index