detect pkghash allocation failure
If rehash ever failed with a full hash it would return the old hash that is already full. get_hash_position would then loop forever because it would never find an empty bucket. Signed-off-by: Andrew Gregory <andrew.gregory.8@gmail.com> Signed-off-by: Allan McRae <allan@archlinux.org>
This commit is contained in:
parent
59b6fdeee1
commit
2bda849bf9
5 changed files with 28 additions and 14 deletions
|
@ -601,7 +601,10 @@ static int local_db_populate(alpm_db_t *db)
|
||||||
/* add to the collection */
|
/* add to the collection */
|
||||||
_alpm_log(db->handle, ALPM_LOG_FUNCTION, "adding '%s' to package cache for db '%s'\n",
|
_alpm_log(db->handle, ALPM_LOG_FUNCTION, "adding '%s' to package cache for db '%s'\n",
|
||||||
pkg->name, db->treename);
|
pkg->name, db->treename);
|
||||||
db->pkgcache = _alpm_pkghash_add(db->pkgcache, pkg);
|
if(_alpm_pkghash_add(&db->pkgcache, pkg) == NULL) {
|
||||||
|
_alpm_pkg_free(pkg);
|
||||||
|
RET_ERR(db->handle, ALPM_ERR_MEMORY, -1);
|
||||||
|
}
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -413,7 +413,10 @@ static alpm_pkg_t *load_pkg_for_entry(alpm_db_t *db, const char *entryname,
|
||||||
/* add to the collection */
|
/* add to the collection */
|
||||||
_alpm_log(db->handle, ALPM_LOG_FUNCTION, "adding '%s' to package cache for db '%s'\n",
|
_alpm_log(db->handle, ALPM_LOG_FUNCTION, "adding '%s' to package cache for db '%s'\n",
|
||||||
pkg->name, db->treename);
|
pkg->name, db->treename);
|
||||||
db->pkgcache = _alpm_pkghash_add(db->pkgcache, pkg);
|
if(_alpm_pkghash_add(&db->pkgcache, pkg) == NULL) {
|
||||||
|
_alpm_pkg_free(pkg);
|
||||||
|
RET_ERR(db->handle, ALPM_ERR_MEMORY, NULL);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
free(pkgname);
|
free(pkgname);
|
||||||
free(pkgver);
|
free(pkgver);
|
||||||
|
|
|
@ -589,7 +589,10 @@ int _alpm_db_add_pkgincache(alpm_db_t *db, alpm_pkg_t *pkg)
|
||||||
? ALPM_PKG_FROM_LOCALDB
|
? ALPM_PKG_FROM_LOCALDB
|
||||||
: ALPM_PKG_FROM_SYNCDB;
|
: ALPM_PKG_FROM_SYNCDB;
|
||||||
newpkg->origin_data.db = db;
|
newpkg->origin_data.db = db;
|
||||||
db->pkgcache = _alpm_pkghash_add_sorted(db->pkgcache, newpkg);
|
if(_alpm_pkghash_add_sorted(&db->pkgcache, newpkg) == NULL) {
|
||||||
|
_alpm_pkg_free(newpkg);
|
||||||
|
RET_ERR(db->handle, ALPM_ERR_MEMORY, -1);
|
||||||
|
}
|
||||||
|
|
||||||
free_groupcache(db);
|
free_groupcache(db);
|
||||||
|
|
||||||
|
|
|
@ -132,8 +132,7 @@ static alpm_pkghash_t *rehash(alpm_pkghash_t *oldhash)
|
||||||
|
|
||||||
newhash = _alpm_pkghash_create(newsize);
|
newhash = _alpm_pkghash_create(newsize);
|
||||||
if(newhash == NULL) {
|
if(newhash == NULL) {
|
||||||
/* creation of newhash failed, stick with old one... */
|
return NULL;
|
||||||
return oldhash;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
newhash->list = oldhash->list;
|
newhash->list = oldhash->list;
|
||||||
|
@ -156,23 +155,29 @@ static alpm_pkghash_t *rehash(alpm_pkghash_t *oldhash)
|
||||||
return newhash;
|
return newhash;
|
||||||
}
|
}
|
||||||
|
|
||||||
static alpm_pkghash_t *pkghash_add_pkg(alpm_pkghash_t *hash, alpm_pkg_t *pkg,
|
static alpm_pkghash_t *pkghash_add_pkg(alpm_pkghash_t **hashref, alpm_pkg_t *pkg,
|
||||||
int sorted)
|
int sorted)
|
||||||
{
|
{
|
||||||
alpm_list_t *ptr;
|
alpm_list_t *ptr;
|
||||||
unsigned int position;
|
unsigned int position;
|
||||||
|
alpm_pkghash_t *hash;
|
||||||
|
|
||||||
if(pkg == NULL || hash == NULL) {
|
if(pkg == NULL || hashref == NULL || *hashref == NULL) {
|
||||||
return hash;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
hash = *hashref;
|
||||||
|
|
||||||
if(hash->entries >= hash->limit) {
|
if(hash->entries >= hash->limit) {
|
||||||
hash = rehash(hash);
|
if((hash = rehash(hash)) == NULL) {
|
||||||
|
/* resizing failed and there are no more open buckets */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
*hashref = hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
position = get_hash_position(pkg->name_hash, hash);
|
position = get_hash_position(pkg->name_hash, hash);
|
||||||
|
|
||||||
MALLOC(ptr, sizeof(alpm_list_t), return hash);
|
MALLOC(ptr, sizeof(alpm_list_t), return NULL);
|
||||||
|
|
||||||
ptr->data = pkg;
|
ptr->data = pkg;
|
||||||
ptr->prev = ptr;
|
ptr->prev = ptr;
|
||||||
|
@ -189,12 +194,12 @@ static alpm_pkghash_t *pkghash_add_pkg(alpm_pkghash_t *hash, alpm_pkg_t *pkg,
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
alpm_pkghash_t *_alpm_pkghash_add(alpm_pkghash_t *hash, alpm_pkg_t *pkg)
|
alpm_pkghash_t *_alpm_pkghash_add(alpm_pkghash_t **hash, alpm_pkg_t *pkg)
|
||||||
{
|
{
|
||||||
return pkghash_add_pkg(hash, pkg, 0);
|
return pkghash_add_pkg(hash, pkg, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
alpm_pkghash_t *_alpm_pkghash_add_sorted(alpm_pkghash_t *hash, alpm_pkg_t *pkg)
|
alpm_pkghash_t *_alpm_pkghash_add_sorted(alpm_pkghash_t **hash, alpm_pkg_t *pkg)
|
||||||
{
|
{
|
||||||
return pkghash_add_pkg(hash, pkg, 1);
|
return pkghash_add_pkg(hash, pkg, 1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,8 +49,8 @@ typedef struct __alpm_pkghash_t alpm_pkghash_t;
|
||||||
|
|
||||||
alpm_pkghash_t *_alpm_pkghash_create(unsigned int size);
|
alpm_pkghash_t *_alpm_pkghash_create(unsigned int size);
|
||||||
|
|
||||||
alpm_pkghash_t *_alpm_pkghash_add(alpm_pkghash_t *hash, alpm_pkg_t *pkg);
|
alpm_pkghash_t *_alpm_pkghash_add(alpm_pkghash_t **hash, alpm_pkg_t *pkg);
|
||||||
alpm_pkghash_t *_alpm_pkghash_add_sorted(alpm_pkghash_t *hash, alpm_pkg_t *pkg);
|
alpm_pkghash_t *_alpm_pkghash_add_sorted(alpm_pkghash_t **hash, alpm_pkg_t *pkg);
|
||||||
alpm_pkghash_t *_alpm_pkghash_remove(alpm_pkghash_t *hash, alpm_pkg_t *pkg, alpm_pkg_t **data);
|
alpm_pkghash_t *_alpm_pkghash_remove(alpm_pkghash_t *hash, alpm_pkg_t *pkg, alpm_pkg_t **data);
|
||||||
|
|
||||||
void _alpm_pkghash_free(alpm_pkghash_t *hash);
|
void _alpm_pkghash_free(alpm_pkghash_t *hash);
|
||||||
|
|
Loading…
Add table
Reference in a new issue