Fix a bug in matching suffixes. Under certain circumstances the code

would access memory before the beginning of the string to match (the
suffix match starts at the end of both the string and the suffix and
proceedes to the begin until either the start of the suffix is hit
or the character does not match). This could lead to a memcpy copying
into random memory. Fix this by checking the length of the string to
match too and replacing the Lst_Find calls with LST_FOREACH loops
(last part by me).

Submitted by:	Matt Dillon <dillon@apollo.backplane.com> (in principle)
This commit is contained in:
harti 2005-03-18 15:16:09 +00:00
parent 285d285103
commit 3754e8fb58

View File

@ -90,6 +90,7 @@ __FBSDID("$FreeBSD$");
* if the target had no implicit sources.
*/
#include <assert.h>
#include <string.h>
#include <stdlib.h>
@ -194,8 +195,7 @@ SuffStrIsPrefix(const char *pref, char *str)
/*-
*-----------------------------------------------------------------------
* SuffSuffIsSuffix --
* See if suff is a suffix of str. Str should point to THE END of the
* string to check. (THE END == the null byte)
* See if suff is a suffix of str.
*
* Results:
* NULL if it ain't, pointer to character in str before suffix if
@ -210,50 +210,21 @@ SuffSuffIsSuffix(const Suff *s, char *str)
{
const char *p1; /* Pointer into suffix name */
char *p2; /* Pointer into string being examined */
size_t len;
len = strlen(str);
p1 = s->name + s->nameLen;
p2 = str;
p2 = str + len;
while (p1 >= s->name && *p1 == *p2) {
while (p1 >= s->name && len > 0 && *p1 == *p2) {
p1--;
p2--;
len--;
}
return (p1 == s->name - 1 ? p2 : NULL);
}
/*-
*-----------------------------------------------------------------------
* SuffSuffIsSuffixP --
* Predicate form of SuffSuffIsSuffix. Passed as the callback function
* to Lst_Find.
*
* Results:
* 0 if the suffix is the one desired, non-zero if not.
*
* Side Effects:
* None.
*
* XXX use the function above once constification is complete.
*-----------------------------------------------------------------------
*/
static int
SuffSuffIsSuffixP(const void *is, const void *str)
{
const Suff *s = is;
const char *p1; /* Pointer into suffix name */
const char *p2 = str; /* Pointer into string being examined */
p1 = s->name + s->nameLen;
while (p1 >= s->name && *p1 == *p2) {
p1--;
p2--;
}
return (p1 != s->name - 1);
}
/*-
*-----------------------------------------------------------------------
* SuffSuffHasNameP --
@ -721,9 +692,9 @@ SuffRebuildGraph(const GNode *transform, Suff *s)
}
/*
* Not from, maybe to?
*/
cp = SuffSuffIsSuffix(s, transform->name + strlen(transform->name));
* Not from, maybe to?
*/
cp = SuffSuffIsSuffix(s, transform->name);
if (cp != NULL) {
/*
* Null-terminate the source suffix in order to find it.
@ -1355,8 +1326,10 @@ SuffExpandWildcards(GNode *child, Lst *members)
* suffix, use its path.
* Else use the default system search path.
*/
cp = child->name + strlen(child->name);
ln = Lst_Find(&sufflist, cp, SuffSuffIsSuffixP);
LST_FOREACH(ln, &sufflist) {
if (SuffSuffIsSuffix(Lst_Datum(ln), child->name) != NULL)
break;
}
DEBUGF(SUFF, ("Wildcard expanding \"%s\"...", child->name));
@ -1682,7 +1655,10 @@ SuffFindArchiveDeps(GNode *gn, Lst *slst)
/*
* Use first matching suffix...
*/
ln = Lst_Find(&ms->parents, eoarch, SuffSuffIsSuffixP);
LST_FOREACH(ln, &ms->parents) {
if (SuffSuffIsSuffix(Lst_Datum(ln), gn->name) != NULL)
break;
}
if (ln != NULL) {
/*
@ -1780,8 +1756,12 @@ SuffFindNormalDeps(GNode *gn, Lst *slst)
/*
* Look for next possible suffix...
*/
ln = Lst_FindFrom(&sufflist, ln, eoname, SuffSuffIsSuffixP);
while (ln != NULL) {
if (SuffSuffIsSuffix(Lst_Datum(ln), gn->name) != NULL)
break;
ln = LST_NEXT(ln);
}
if (ln != NULL) {
int prefLen; /* Length of the prefix */
Src *target;
@ -1800,6 +1780,7 @@ SuffFindNormalDeps(GNode *gn, Lst *slst)
* the end of the name.
*/
prefLen = (eoname - target->suff->nameLen) - sopref;
assert(prefLen >= 0);
target->pref = emalloc(prefLen + 1);
memcpy(target->pref, sopref, prefLen);
target->pref[prefLen] = '\0';