Correctly allocate strings when filtering them ##bin

* bin/filter: correctly allocate strings when filtering them

Directly reallocate strings when filtering them, because it is very hard for
the caller to know before hand the correct size of the string otherwise. The
patch uses r_str_ APIs to makes this easy.
This commit is contained in:
Riccardo Schirone 2018-11-12 00:04:41 +01:00 committed by radare
parent b6c3425610
commit a6a04332f8
3 changed files with 35 additions and 33 deletions

View File

@ -3,54 +3,59 @@
#include <r_bin.h>
#include "i/private.h"
static void hashify(char *s, ut64 vaddr) {
if (!s) {
return;
}
static char *hashify(char *s, ut64 vaddr) {
r_return_val_if_fail (s, NULL);
char *os = s;
while (*s) {
if (!IS_PRINTABLE (*s)) {
free (os);
if (vaddr && vaddr != UT64_MAX) {
sprintf (s, "_%" PFMT64d, vaddr);
return r_str_newf ("_%" PFMT64d, vaddr);
} else {
ut32 hash = sdb_hash (s);
sprintf (s, "%x", hash);
return r_str_newf ("%x", hash);
}
return;
}
s++;
}
return os;
}
// TODO: optimize this api:
// - bin plugins should call r_bin_filter_name() before appending
R_API void r_bin_filter_name(RBinFile *bf, Sdb *db, ut64 vaddr, char *name, int maxlen) {
// - name should be allocated on the heap
R_API char *r_bin_filter_name(RBinFile *bf, Sdb *db, ut64 vaddr, char *name) {
r_return_val_if_fail (db && name, NULL);
const char *uname;
char *resname = name;
ut32 vhash, hash;
int count;
if (!db || !name) {
return;
}
uname = sdb_fmt ("%" PFMT64x ".%s", vaddr, name);
uname = sdb_fmt ("%" PFMT64x ".%s", vaddr, resname);
vhash = sdb_hash (uname); // vaddr hash - unique
hash = sdb_hash (name); // name hash - if dupped and not in unique hash must insert
hash = sdb_hash (resname); // name hash - if dupped and not in unique hash must insert
count = sdb_num_inc (db, sdb_fmt ("%x", hash), 1, 0);
if (sdb_exists (db, sdb_fmt ("%x", vhash))) {
// TODO: symbol is dupped, so symbol can be removed!
return;
return resname;
}
sdb_num_set (db, sdb_fmt ("%x", vhash), 1, 0);
if (vaddr) {
hashify (name, vaddr);
char *p = hashify (resname, vaddr);
if (p) {
resname = p;
}
}
if (count > 1) {
int namelen = strlen (name);
if (namelen > maxlen) {
name[maxlen] = 0;
char *p = r_str_appendf (resname, "_%d", count - 1);
if (p) {
resname = p;
}
strcat (name, sdb_fmt ("_%d", count - 1));
// two symbols at different addresses and same name wtf
// eprintf ("Symbol '%s' dupped!\n", sym->name);
}
return resname;
}
R_API void r_bin_filter_sym(RBinFile *bf, Sdb *db, ut64 vaddr, RBinSymbol *sym) {
@ -95,9 +100,6 @@ R_API void r_bin_filter_sym(RBinFile *bf, Sdb *db, ut64 vaddr, RBinSymbol *sym)
return;
}
sdb_num_set (db, sdb_fmt ("%x", vhash), 1, 0);
if (vaddr) {
//hashify (name, vaddr);
}
sym->dup_count = count - 1;
}
@ -120,14 +122,10 @@ R_API void r_bin_filter_sections(RBinFile *bf, RList *list) {
Sdb *db = sdb_new0 ();
RListIter *iter;
r_list_foreach (list, iter, sec) {
int maxlen = strlen (sec->name) + 8;
char *newbuf = realloc (sec->name, maxlen);
if (!newbuf) {
eprintf ("%s: Failed to reallocate buffer\n", __func__);
continue;
char *p = r_bin_filter_name (bf, db, sec->vaddr, sec->name);
if (p) {
sec->name = p;
}
sec->name = newbuf;
r_bin_filter_name (bf, db, sec->vaddr, sec->name, maxlen);
}
sdb_free (db);
}

View File

@ -240,8 +240,12 @@ static void filter_classes(RBinFile *bf, RList *list) {
int namepad_len = strlen (cls->name) + 32;
char *namepad = malloc (namepad_len + 1);
if (namepad) {
char *p;
strcpy (namepad, cls->name);
r_bin_filter_name (bf, db, cls->index, namepad, namepad_len);
p = r_bin_filter_name (bf, db, cls->index, namepad);
if (p) {
namepad = p;
}
free (cls->name);
cls->name = namepad;
r_list_foreach (cls->methods, iter2, sym) {

View File

@ -725,7 +725,7 @@ R_API RList *r_bin_get_mem(RBin *bin);
R_API void r_bin_load_filter(RBin *bin, ut64 rules);
R_API void r_bin_filter_symbols(RBinFile *bf, RList *list);
R_API void r_bin_filter_sections(RBinFile *bf, RList *list);
R_API void r_bin_filter_name(RBinFile *bf, Sdb *db, ut64 addr, char *name, int maxlen);
R_API char *r_bin_filter_name(RBinFile *bf, Sdb *db, ut64 addr, char *name);
R_API void r_bin_filter_sym(RBinFile *bf, Sdb *db, ut64 vaddr, RBinSymbol *sym);
R_API bool r_bin_strpurge(RBin *bin, const char *str, ut64 addr);
R_API bool r_bin_string_filter(RBin *bin, const char *str, ut64 addr);