OXF-3100, tinyproxy leak fix

This commit is contained in:
amkumar 2021-03-26 09:18:56 +00:00
parent c74fe57262
commit 0e75840bd2
3 changed files with 31 additions and 14 deletions

View File

@ -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;

View File

@ -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);

View File

@ -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;
} }