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:
parent
285d285103
commit
3754e8fb58
@ -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';
|
||||
|
Loading…
Reference in New Issue
Block a user