OXF-3100, tinyproxy leak fix
This commit is contained in:
parent
c74fe57262
commit
0e75840bd2
@ -107,14 +107,14 @@ static int resize(struct htab *htab, size_t nel)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct elem *lookup(struct htab *htab, const char *key, size_t hash)
|
static struct elem *lookup(struct htab *htab, const char *key, size_t hash, size_t dead)
|
||||||
{
|
{
|
||||||
size_t i, j;
|
size_t i, j;
|
||||||
struct elem *e;
|
struct elem *e;
|
||||||
|
|
||||||
for (i=hash,j=1; ; i+=j++) {
|
for (i=hash,j=1; ; i+=j++) {
|
||||||
e = htab->elems + (i & htab->mask);
|
e = htab->elems + (i & htab->mask);
|
||||||
if (!e->item.key ||
|
if ((!e->item.key && (!e->hash || e->hash == dead)) ||
|
||||||
(e->hash==hash && STRCMP(e->item.key, key)==0))
|
(e->hash==hash && STRCMP(e->item.key, key)==0))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -138,36 +138,46 @@ void htab_destroy(struct htab *htab)
|
|||||||
free(htab);
|
free(htab);
|
||||||
}
|
}
|
||||||
|
|
||||||
static htab_entry *htab_find_item(struct htab *htab, const char* key)
|
static struct elem *htab_find_elem(struct htab *htab, const char* key)
|
||||||
{
|
{
|
||||||
size_t hash = keyhash(key, htab->seed);
|
size_t hash = keyhash(key, htab->seed);
|
||||||
struct elem *e = lookup(htab, key, hash);
|
struct elem *e = lookup(htab, key, hash, 0);
|
||||||
|
|
||||||
if (e->item.key) {
|
if (e->item.key) {
|
||||||
return &e->item;
|
return e;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
htab_value* htab_find(struct htab *htab, const char* key)
|
htab_value* htab_find(struct htab *htab, const char* key)
|
||||||
{
|
{
|
||||||
htab_entry *i = htab_find_item(htab, key);
|
struct elem *e = htab_find_elem(htab, key);
|
||||||
if(i) return &i->data;
|
if(!e) return 0;
|
||||||
return 0;
|
return &e->item.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
htab_value* htab_find2(struct htab *htab, const char* key, char **saved_key)
|
||||||
|
{
|
||||||
|
struct elem *e = htab_find_elem(htab, key);
|
||||||
|
if(!e) return 0;
|
||||||
|
*saved_key = e->item.key;
|
||||||
|
return &e->item.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
int htab_delete(struct htab *htab, const char* key)
|
int htab_delete(struct htab *htab, const char* key)
|
||||||
{
|
{
|
||||||
htab_entry *i = htab_find_item(htab, key);
|
struct elem *e = htab_find_elem(htab, key);
|
||||||
if(!i) return 0;
|
if(!e) return 0;
|
||||||
i->key = 0;
|
e->item.key = 0;
|
||||||
|
e->hash = 0xdeadc0de;
|
||||||
|
--htab->used;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int htab_insert(struct htab *htab, char* key, htab_value value)
|
int htab_insert(struct htab *htab, char* key, htab_value value)
|
||||||
{
|
{
|
||||||
size_t hash = keyhash(key, htab->seed);
|
size_t hash = keyhash(key, htab->seed);
|
||||||
struct elem *e = lookup(htab, key, hash);
|
struct elem *e = lookup(htab, key, hash, 0xdeadc0de);
|
||||||
if(e->item.key) {
|
if(e->item.key) {
|
||||||
/* it's not allowed to overwrite existing data */
|
/* it's not allowed to overwrite existing data */
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -14,6 +14,8 @@ typedef union htab_value {
|
|||||||
struct htab * htab_create(size_t);
|
struct htab * htab_create(size_t);
|
||||||
void htab_destroy(struct htab *);
|
void htab_destroy(struct htab *);
|
||||||
htab_value* htab_find(struct htab *, const char* key);
|
htab_value* htab_find(struct htab *, const char* key);
|
||||||
|
/* same as htab_find, but can retrieve the saved key (for freeing) */
|
||||||
|
htab_value* htab_find2(struct htab *htab, const char* key, char **saved_key);
|
||||||
int htab_insert(struct htab *, char*, htab_value);
|
int htab_insert(struct htab *, char*, htab_value);
|
||||||
int htab_delete(struct htab *htab, const char* key);
|
int htab_delete(struct htab *htab, const char* key);
|
||||||
size_t htab_next(struct htab *, size_t iterator, char** key, htab_value **v);
|
size_t htab_next(struct htab *, size_t iterator, char** key, htab_value **v);
|
||||||
|
@ -81,14 +81,19 @@ char* orderedmap_find(struct orderedmap *o, const char *key) {
|
|||||||
int orderedmap_remove(struct orderedmap *o, const char *key) {
|
int orderedmap_remove(struct orderedmap *o, const char *key) {
|
||||||
size_t i;
|
size_t i;
|
||||||
char *lk;
|
char *lk;
|
||||||
htab_value *lv, *v = htab_find(o->map, key);
|
char *sk;
|
||||||
|
char **sv;
|
||||||
|
htab_value *lv, *v = htab_find2(o->map, key, &sk);
|
||||||
if(!v) return 0;
|
if(!v) return 0;
|
||||||
htab_delete(o->map, key);
|
sv = sblist_get(o->values, v->n);
|
||||||
|
free(*sv);
|
||||||
sblist_delete(o->values, v->n);
|
sblist_delete(o->values, v->n);
|
||||||
i = 0;
|
i = 0;
|
||||||
while((i = htab_next(o->map, i, &lk, &lv))) {
|
while((i = htab_next(o->map, i, &lk, &lv))) {
|
||||||
if(lv->n > v->n) lv->n--;
|
if(lv->n > v->n) lv->n--;
|
||||||
}
|
}
|
||||||
|
htab_delete(o->map, key);
|
||||||
|
free(sk);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user