mirror of
https://github.com/reactos/reactos.git
synced 2024-10-05 17:06:29 +00:00
[CDMAKE]
- When deleting a directory entry, also remove it from the hash table. This prevents use after free in the case of a hash collision CORE-7774 #resolve svn path=/trunk/; revision=61643
This commit is contained in:
parent
4aa5c6f093
commit
bcb5f9475e
|
@ -10,7 +10,7 @@ djb_hash(const char *name)
|
||||||
{
|
{
|
||||||
unsigned int val = 5381;
|
unsigned int val = 5381;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
for (i = 0; name[i]; i++)
|
for (i = 0; name[i]; i++)
|
||||||
{
|
{
|
||||||
val = (33 * val) + name[i];
|
val = (33 * val) + name[i];
|
||||||
|
@ -65,6 +65,19 @@ get_entry_by_normname(struct target_dir_hash *dh, const char *norm)
|
||||||
return de;
|
return de;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
delete_entry_by_normname(struct target_dir_hash *dh, const char *norm)
|
||||||
|
{
|
||||||
|
unsigned int hashcode;
|
||||||
|
struct target_dir_entry **ent;
|
||||||
|
hashcode = djb_hash(norm);
|
||||||
|
ent = &dh->buckets[hashcode % NUM_DIR_HASH_BUCKETS];
|
||||||
|
while (*ent && strcmp((*ent)->normalized_name, norm))
|
||||||
|
ent = &(*ent)->next;
|
||||||
|
if (*ent)
|
||||||
|
*ent = (*ent)->next;
|
||||||
|
}
|
||||||
|
|
||||||
void normalize_dirname(char *filename)
|
void normalize_dirname(char *filename)
|
||||||
{
|
{
|
||||||
int i, tgt;
|
int i, tgt;
|
||||||
|
@ -147,9 +160,9 @@ void dir_hash_add_file(struct target_dir_hash *dh, const char *source, const cha
|
||||||
}
|
}
|
||||||
|
|
||||||
struct target_dir_entry *
|
struct target_dir_entry *
|
||||||
dir_hash_next_dir(struct target_dir_hash *dh, struct target_dir_traversal *t)
|
dir_hash_next_dir(struct target_dir_hash *dh, struct target_dir_traversal *t)
|
||||||
{
|
{
|
||||||
if (t->i == -1)
|
if (t->i == -1)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (!t->it)
|
if (!t->it)
|
||||||
{
|
{
|
||||||
|
@ -177,14 +190,16 @@ dir_hash_next_dir(struct target_dir_hash *dh, struct target_dir_traversal *t)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void dir_hash_destroy_dir(struct target_dir_entry *de)
|
static void
|
||||||
|
dir_hash_destroy_dir(struct target_dir_hash *dh, struct target_dir_entry *de)
|
||||||
{
|
{
|
||||||
struct target_file *tf;
|
struct target_file *tf;
|
||||||
struct target_dir_entry *te;
|
struct target_dir_entry *te;
|
||||||
|
unsigned int hashcode;
|
||||||
while ((te = de->child))
|
while ((te = de->child))
|
||||||
{
|
{
|
||||||
de->child = te->next;
|
de->child = te->next;
|
||||||
dir_hash_destroy_dir(te);
|
dir_hash_destroy_dir(dh, te);
|
||||||
free(te);
|
free(te);
|
||||||
}
|
}
|
||||||
while ((tf = de->head))
|
while ((tf = de->head))
|
||||||
|
@ -194,11 +209,12 @@ void dir_hash_destroy_dir(struct target_dir_entry *de)
|
||||||
free(tf->target_name);
|
free(tf->target_name);
|
||||||
free(tf);
|
free(tf);
|
||||||
}
|
}
|
||||||
|
delete_entry_by_normname(dh, de->normalized_name);
|
||||||
free(de->normalized_name);
|
free(de->normalized_name);
|
||||||
free(de->case_name);
|
free(de->case_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void dir_hash_destroy(struct target_dir_hash *dh)
|
void dir_hash_destroy(struct target_dir_hash *dh)
|
||||||
{
|
{
|
||||||
dir_hash_destroy_dir(&dh->root);
|
dir_hash_destroy_dir(dh, &dh->root);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue