mirror of
https://github.com/radareorg/radare2.git
synced 2024-11-28 15:41:38 +00:00
added free function into RHashTable (#5249)
This commit is contained in:
parent
09435c7317
commit
34fae270dd
@ -23,6 +23,9 @@ static int cmpfun(void *a, void *b) {
|
||||
R_API RListRange* r_listrange_new () {
|
||||
RListRange *s = R_NEW (RListRange);
|
||||
s->h = r_hashtable64_new ();
|
||||
s->h->free = (RHashFree)r_list_free;
|
||||
//s->l shouldn't free is a helper structure to get data in order
|
||||
//s->h will free the list that contains RAnalFunction
|
||||
s->l = r_list_new ();
|
||||
return s;
|
||||
}
|
||||
@ -58,11 +61,10 @@ R_API void r_listrange_add(RListRange *s, RAnalFunction *f) {
|
||||
list = r_hashtable64_lookup (s->h, key);
|
||||
if (list) {
|
||||
if (!r_list_contains (list, f))
|
||||
//r_list_add_sorted (list, f, cmpfun);
|
||||
r_list_append (list, f);
|
||||
} else {
|
||||
list = r_list_new ();
|
||||
//r_list_add_sorted (list, f, cmpfun);
|
||||
list->free = (RListFree)r_anal_fcn_free;
|
||||
r_list_append (list, f);
|
||||
r_hashtable64_insert (s->h, key, list);
|
||||
}
|
||||
@ -76,7 +78,7 @@ R_API void r_listrange_del(RListRange *s, RAnalFunction *f) {
|
||||
if (!f) return;
|
||||
from = f->addr;
|
||||
to = f->addr + f->size;
|
||||
for (addr = from; addr<to; addr = r_listrange_next (addr)) {
|
||||
for (addr = from; addr < to; addr = r_listrange_next (addr)) {
|
||||
list = r_hashtable64_lookup (s->h, r_listrange_key (addr));
|
||||
if (list) r_list_delete_data (list, f);
|
||||
}
|
||||
|
@ -14,7 +14,7 @@
|
||||
#define IFDBG if(DO_THE_DBG)
|
||||
#define IFINT if(0)
|
||||
|
||||
R_API RAnalState * r_anal_state_new (ut64 start, ut8* buffer, ut64 len) {
|
||||
R_API RAnalState * r_anal_state_new(ut64 start, ut8* buffer, ut64 len) {
|
||||
RAnalState *state = R_NEW0 (RAnalState);
|
||||
if (!state) return NULL;
|
||||
state->start = start;
|
||||
@ -25,6 +25,7 @@ R_API RAnalState * r_anal_state_new (ut64 start, ut8* buffer, ut64 len) {
|
||||
state->current_bb = NULL;
|
||||
state->current_fcn = NULL;
|
||||
state->ht = r_hashtable64_new();
|
||||
state->ht->free = (RHashFree)r_anal_bb_free;
|
||||
state->ht_sz = 512;
|
||||
state->bbs = r_list_new();
|
||||
state->max_depth = 50;
|
||||
@ -37,7 +38,7 @@ R_API void r_anal_state_set_depth(RAnalState *state, ut32 depth) {
|
||||
state->current_depth = depth;
|
||||
}
|
||||
|
||||
R_API void r_anal_state_insert_bb (RAnalState* state, RAnalBlock *bb) {
|
||||
R_API void r_anal_state_insert_bb(RAnalState* state, RAnalBlock *bb) {
|
||||
if (!state || !bb)
|
||||
return;
|
||||
if (r_anal_state_search_bb (state, bb->addr) == NULL &&
|
||||
@ -56,7 +57,7 @@ R_API void r_anal_state_insert_bb (RAnalState* state, RAnalBlock *bb) {
|
||||
}
|
||||
}
|
||||
}
|
||||
R_API RAnalBlock * r_anal_state_search_bb (RAnalState* state, ut64 addr) {
|
||||
R_API RAnalBlock * r_anal_state_search_bb(RAnalState* state, ut64 addr) {
|
||||
/*
|
||||
* Return 0 if no rehash is needed, otherwise return 1
|
||||
*/
|
||||
@ -64,13 +65,13 @@ R_API RAnalBlock * r_anal_state_search_bb (RAnalState* state, ut64 addr) {
|
||||
return tmp_bb;
|
||||
}
|
||||
|
||||
R_API void r_anal_state_free (RAnalState * state) {
|
||||
r_list_free(state->bbs);
|
||||
r_hashtable64_free(state->ht);
|
||||
free(state);
|
||||
R_API void r_anal_state_free(RAnalState * state) {
|
||||
r_list_free (state->bbs);
|
||||
r_hashtable64_free (state->ht);
|
||||
free (state);
|
||||
}
|
||||
|
||||
R_API ut64 r_anal_state_get_len (RAnalState *state, ut64 addr) {
|
||||
R_API ut64 r_anal_state_get_len(RAnalState *state, ut64 addr) {
|
||||
ut64 result = 0;
|
||||
if (r_anal_state_addr_is_valid (state, addr)) {
|
||||
result = state->len - (addr - state->start);
|
||||
@ -78,7 +79,7 @@ R_API ut64 r_anal_state_get_len (RAnalState *state, ut64 addr) {
|
||||
return result;
|
||||
}
|
||||
|
||||
R_API const ut8 * r_anal_state_get_buf_by_addr (RAnalState *state, ut64 addr) {
|
||||
R_API const ut8 * r_anal_state_get_buf_by_addr(RAnalState *state, ut64 addr) {
|
||||
if (r_anal_state_addr_is_valid (state, addr)) {
|
||||
ut64 offset = addr - state->start;
|
||||
return state->buffer+offset;
|
||||
@ -86,7 +87,7 @@ R_API const ut8 * r_anal_state_get_buf_by_addr (RAnalState *state, ut64 addr) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
R_API bool r_anal_state_addr_is_valid (RAnalState *state, ut64 addr) {
|
||||
R_API bool r_anal_state_addr_is_valid(RAnalState *state, ut64 addr) {
|
||||
return (addr < state->end && addr >= state->start);
|
||||
}
|
||||
|
||||
@ -94,7 +95,7 @@ R_API void r_anal_state_merge_bb_list (RAnalState *state, RList* bbs) {
|
||||
RListIter *iter;
|
||||
RAnalBlock *bb;
|
||||
r_list_foreach (bbs, iter, bb) {
|
||||
IFDBG eprintf ("Inserting bb fron 0x%04"PFMT64x"\n", bb->addr);
|
||||
IFDBG eprintf ("Inserting bb from 0x%04"PFMT64x"\n", bb->addr);
|
||||
r_anal_state_insert_bb (state, bb);
|
||||
}
|
||||
}
|
||||
|
@ -36,10 +36,7 @@ static void remove_offsetmap(RFlag *f, RFlagItem *item) {
|
||||
if (fs_off) {
|
||||
r_list_delete_data (fs_off, item);
|
||||
if (r_list_empty (fs_off)) {
|
||||
//make sure to free the list
|
||||
RList *tmp_list = r_hashtable64_lookup (f->ht_off, XOROFF(item->offset));
|
||||
r_hashtable64_remove (f->ht_off, XOROFF (item->offset));
|
||||
r_list_free (tmp_list);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -83,7 +80,10 @@ R_API RFlag * r_flag_new() {
|
||||
return NULL;
|
||||
}
|
||||
f->ht_name = r_hashtable64_new ();
|
||||
|
||||
f->ht_off = r_hashtable64_new ();
|
||||
f->ht_off->free = (RHashFree)r_list_free;
|
||||
|
||||
for (i = 0; i < R_FLAG_SPACES_MAX; i++) {
|
||||
f->spaces[i] = NULL;
|
||||
}
|
||||
@ -91,13 +91,17 @@ R_API RFlag * r_flag_new() {
|
||||
}
|
||||
|
||||
R_API void r_flag_item_free(RFlagItem *item) {
|
||||
free (item->color);
|
||||
free (item->comment);
|
||||
free (item->alias);
|
||||
/* release only one of the two pointers if they are the same */
|
||||
if (item->name != item->realname) free (item->name);
|
||||
free (item->realname);
|
||||
free (item);
|
||||
if (item) {
|
||||
free (item->color);
|
||||
free (item->comment);
|
||||
free (item->alias);
|
||||
/* release only one of the two pointers if they are the same */
|
||||
if (item->name != item->realname) {
|
||||
free (item->name);
|
||||
}
|
||||
free (item->realname);
|
||||
R_FREE (item);
|
||||
}
|
||||
}
|
||||
|
||||
R_API RFlag *r_flag_free(RFlag *f) {
|
||||
@ -106,10 +110,6 @@ R_API RFlag *r_flag_free(RFlag *f) {
|
||||
for (i = 0; i < R_FLAG_SPACES_MAX; i++) {
|
||||
free (f->spaces[i]);
|
||||
}
|
||||
//in our case this is a list so just make sure to free it up
|
||||
for (i = 0; i < f->ht_off->size_index; i++) {
|
||||
r_list_free (f->ht_off->table[i].data);
|
||||
}
|
||||
r_hashtable64_free (f->ht_off);
|
||||
r_hashtable64_free (f->ht_name);
|
||||
r_list_free (f->flags);
|
||||
@ -317,6 +317,8 @@ R_API RFlagItem *r_flag_set(RFlag *f, const char *name, ut64 off, ut32 size) {
|
||||
free (item);
|
||||
return NULL;
|
||||
}
|
||||
//item share ownership prone to uaf, that is why only
|
||||
//f->flags has set up free pointer
|
||||
r_hashtable64_insert (f->ht_name, item->namehash, item);
|
||||
r_list_append (f->flags, item);
|
||||
}
|
||||
@ -395,7 +397,7 @@ R_API int r_flag_unset(RFlag *f, RFlagItem *item) {
|
||||
R_API int r_flag_unset_off(RFlag *f, ut64 off) {
|
||||
RFlagItem *item = r_flag_get_i (f, off);
|
||||
if (item && r_flag_unset (f, item)) {
|
||||
free (item);
|
||||
R_FREE (item);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -427,7 +429,7 @@ R_API int r_flag_unset_name(RFlag *f, const char *name) {
|
||||
ut64 hash = r_str_hash64 (name);
|
||||
RFlagItem *item = r_hashtable64_lookup (f->ht_name, hash);
|
||||
if (item && r_flag_unset (f, item)) {
|
||||
free (item);
|
||||
R_FREE (item);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -440,12 +442,15 @@ R_API void r_flag_unset_all(RFlag *f) {
|
||||
r_list_free (f->flags);
|
||||
f->flags = r_list_new ();
|
||||
if (!f->flags) return;
|
||||
f->flags->free = (RListFree) r_flag_item_free;
|
||||
f->flags->free = (RListFree)r_flag_item_free;
|
||||
|
||||
r_hashtable64_free (f->ht_name);
|
||||
//don't set free since f->flags will free up items when needed avoiding uaf
|
||||
f->ht_name = r_hashtable64_new ();
|
||||
|
||||
r_hashtable64_free (f->ht_off);
|
||||
f->ht_off = r_hashtable64_new ();
|
||||
f->ht_off->free = (RHashFree)r_list_free;
|
||||
|
||||
r_flag_space_unset (f, NULL);
|
||||
}
|
||||
|
@ -5,6 +5,9 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
typedef void (*RHashFree)(void *ptr);
|
||||
|
||||
/** hashtable **/
|
||||
typedef struct r_hashtable_entry_t {
|
||||
ut32 hash;
|
||||
@ -19,6 +22,7 @@ typedef struct r_hashtable_t {
|
||||
ut32 size_index;
|
||||
ut32 entries;
|
||||
ut32 deleted_entries;
|
||||
RHashFree free; //function pointer to free data in table
|
||||
} RHashTable;
|
||||
|
||||
typedef struct r_hashtable64_entry_t {
|
||||
@ -34,6 +38,7 @@ typedef struct r_hashtable64_t {
|
||||
ut64 size_index;
|
||||
ut64 entries;
|
||||
ut64 deleted_entries;
|
||||
RHashFree free; //function pointer to free data in table
|
||||
} RHashTable64;
|
||||
|
||||
R_API RHashTable* r_hashtable_new(void);
|
||||
|
@ -165,11 +165,19 @@ R_API RHT* ht_(new)(void) {
|
||||
ht->deleted_entries = 0;
|
||||
ht->rehash = hash_sizes[ht->size_index].rehash;
|
||||
ht->max_entries = hash_sizes[ht->size_index].max_entries;
|
||||
ht->free = NULL;
|
||||
return ht;
|
||||
}
|
||||
|
||||
R_API void ht_(free)(RHT *ht) {
|
||||
if (ht) {
|
||||
if (ht->free) {
|
||||
int i;
|
||||
for (i = 0; i < ht->size; i++) {
|
||||
ht->free (ht->table[i].data);
|
||||
ht->table[i].data = NULL;
|
||||
}
|
||||
}
|
||||
free (ht->table);
|
||||
free (ht);
|
||||
}
|
||||
@ -189,7 +197,7 @@ R_API void *ht_(lookup)(RHT *ht, utH hash) {
|
||||
* Note that insertion may rearrange the table on a resize or rehash,
|
||||
* so previously found hash_entries are no longer valid after this function.
|
||||
*/
|
||||
R_API bool ht_(insert) (RHT *ht, utH hash, void *data) {
|
||||
R_API bool ht_(insert)(RHT *ht, utH hash, void *data) {
|
||||
utH hash_address;
|
||||
|
||||
if (ht->entries >= ht->max_entries)
|
||||
@ -208,7 +216,7 @@ R_API bool ht_(insert) (RHT *ht, utH hash, void *data) {
|
||||
entry->hash = hash;
|
||||
entry->data = data;
|
||||
ht->entries++;
|
||||
return R_TRUE;
|
||||
return true;
|
||||
}
|
||||
double_hash = hash % ht->rehash;
|
||||
if (double_hash == 0)
|
||||
@ -219,13 +227,16 @@ R_API bool ht_(insert) (RHT *ht, utH hash, void *data) {
|
||||
/* We could hit here if a required resize failed. An unchecked-malloc
|
||||
* application could ignore this result.
|
||||
*/
|
||||
return R_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
R_API void ht_(remove) (RHT *ht, utH hash) {
|
||||
R_API void ht_(remove)(RHT *ht, utH hash) {
|
||||
RHTE *entry = ht_(search) (ht, hash);
|
||||
if (entry) {
|
||||
entry->hash = DELETED_HASH;
|
||||
if (ht->free) {
|
||||
ht->free (entry->data);
|
||||
}
|
||||
entry->data = NULL;
|
||||
ht->entries--;
|
||||
ht->deleted_entries++;
|
||||
|
@ -296,12 +296,12 @@ fail:
|
||||
|
||||
// Compute a 64 bit DJB hash of a string.
|
||||
R_API ut64 r_str_hash64(const char *s) {
|
||||
ut64 len, h = 5381;
|
||||
ut64 len, h = 5381;
|
||||
if (!s)
|
||||
return 0;
|
||||
for (len=strlen (s); len>0; len--)
|
||||
h = (h^(h<<5)) ^ *s++;
|
||||
return h;
|
||||
for (len = strlen (s); len > 0; len--)
|
||||
h = (h ^ (h << 5)) ^ *s++;
|
||||
return h;
|
||||
}
|
||||
|
||||
// Compute a 32bit DJB hash of a string.
|
||||
|
Loading…
Reference in New Issue
Block a user