1
0
mirror of https://gitlab.gnome.org/GNOME/libxml2.git synced 2025-03-24 06:50:08 +03:00

malloc-fail: Grow hash tables before making allocations

Fix short-lived memory leak found by OSS-Fuzz.
This commit is contained in:
Nick Wellnhofer 2023-09-30 17:02:46 +02:00
parent 80a0580f23
commit 61e29b6949
2 changed files with 44 additions and 44 deletions

14
dict.c

@ -698,13 +698,6 @@ xmlDictLookupInternal(xmlDictPtr dict, const xmlChar *prefix,
if (!update)
return(NULL);
if (prefix == NULL)
ret = xmlDictAddString(dict, name, len);
else
ret = xmlDictAddQString(dict, prefix, plen, name, len);
if (ret == NULL)
return(NULL);
/*
* Grow the hash table if needed
*/
@ -739,6 +732,13 @@ xmlDictLookupInternal(xmlDictPtr dict, const xmlChar *prefix,
}
}
if (prefix == NULL)
ret = xmlDictAddString(dict, name, len);
else
ret = xmlDictAddQString(dict, prefix, plen, name, len);
if (ret == NULL)
return(NULL);
/*
* Shift the remainder of the probe sequence to the right
*/

74
hash.c

@ -457,6 +457,43 @@ xmlHashUpdateInternal(xmlHashTablePtr hash, const xmlChar *key,
}
}
/*
* Grow the hash table if needed
*/
if (hash->nbElems + 1 > hash->size / MAX_FILL_DENOM * MAX_FILL_NUM) {
unsigned newSize, mask, displ, pos;
if (hash->size == 0) {
newSize = MIN_HASH_SIZE;
} else {
/* This guarantees that nbElems < INT_MAX */
if (hash->size >= MAX_HASH_SIZE)
return(-1);
newSize = hash->size * 2;
}
if (xmlHashGrow(hash, newSize) != 0)
return(-1);
/*
* Find new entry
*/
mask = hash->size - 1;
displ = 0;
pos = hashValue & mask;
entry = &hash->table[pos];
if (entry->hashValue != 0) {
do {
displ++;
pos++;
entry++;
if ((pos & mask) == 0)
entry = hash->table;
} while ((entry->hashValue != 0) &&
((pos - entry->hashValue) & mask) >= displ);
}
}
/*
* Copy keys
*/
@ -513,43 +550,6 @@ xmlHashUpdateInternal(xmlHashTablePtr hash, const xmlChar *key,
}
}
/*
* Grow the hash table if needed
*/
if (hash->nbElems + 1 > hash->size / MAX_FILL_DENOM * MAX_FILL_NUM) {
unsigned newSize, mask, displ, pos;
if (hash->size == 0) {
newSize = MIN_HASH_SIZE;
} else {
/* This guarantees that nbElems < INT_MAX */
if (hash->size >= MAX_HASH_SIZE)
return(-1);
newSize = hash->size * 2;
}
if (xmlHashGrow(hash, newSize) != 0)
return(-1);
/*
* Find new entry
*/
mask = hash->size - 1;
displ = 0;
pos = hashValue & mask;
entry = &hash->table[pos];
if (entry->hashValue != 0) {
do {
displ++;
pos++;
entry++;
if ((pos & mask) == 0)
entry = hash->table;
} while ((entry->hashValue != 0) &&
((pos - entry->hashValue) & mask) >= displ);
}
}
/*
* Shift the remainder of the probe sequence to the right
*/