Update sdb and fix #777 - pxq and pxw honors cfg.big_endian

This commit is contained in:
pancake 2014-04-10 19:17:24 +02:00
parent 1808ae3d22
commit 10f2439c5d
11 changed files with 167 additions and 46 deletions

View File

@ -217,3 +217,4 @@ In Soviet Russia, Radare have documentation
Initial frame selected; you cannot go up.
unk, unk, unk, unk
Experts agree, security holes suck, and we fixed some of them!
r2 your penis

View File

@ -340,6 +340,15 @@ R_API int r_anal_fcn_insert(RAnal *anal, RAnalFunction *fcn) {
#if USE_NEW_FCN_STORE
r_listrange_add (anal->fcnstore, fcn);
// HUH? store it here .. for backweird compatibility
#endif
#if ANAL_FCN_SDB
#if 0
// override bits, size,
fcn.<offset>=name,size,type
fcn.<offset>.bbs
fcn.name.<name>=<offset>
#endif
sdb_set (DB, "fcn.0x080", "
#endif
r_list_append (anal->fcns, fcn);
return R_TRUE;

View File

@ -33,6 +33,7 @@ extern "C" {
#define SDB_OPTION_NOSTAMP 2
#define SDB_OPTION_FS 4
// This size implies trailing zero terminator, this is 254 chars + 0
#define SDB_KSZ 0xff
typedef struct sdb_kv {

View File

@ -372,6 +372,7 @@ static int check_sparse (const ut8 *p, int len, int ch) {
// XXX: step is borken
R_API void r_print_hexdump(RPrint *p, ut64 addr, const ut8 *buf, int len, int base, int step) {
PrintfCallback printfmt = (PrintfCallback) printf;
int i, j, k, inc = 16;
int sparse_char = 0;
int stride = 0;
@ -383,7 +384,6 @@ R_API void r_print_hexdump(RPrint *p, ut64 addr, const ut8 *buf, int len, int ba
const char *fmt = "%02x";
const char *pre = "";
int last_sparse = 0;
PrintfCallback printfmt = (PrintfCallback) printf;
if (p) {
use_sparse = p->flags & R_PRINT_FLAGS_SPARSE;
@ -473,22 +473,20 @@ R_API void r_print_hexdump(RPrint *p, ut64 addr, const ut8 *buf, int len, int ba
continue;
}
if (base==32) {
ut32 n;
memcpy (&n, buf+j, sizeof (n));
ut32 n = 0;
r_mem_copyendian ((ut8*)&n, buf+j, sizeof (n), !p->big_endian);
r_print_cursor (p, j, 1);
printfmt ("0x%08x ", n);
r_print_cursor (p, j, 0);
j += 3;
} else
if (base==64) {
ut32 a, b;
ut64 x = 0LL;
/* Prevent reading outside of buf. Necessary as inc is not
* a multiple of 4 for base == 64. */
// size_t l = sizeof (n); if (j + l > len) l = len - j;
memcpy (&a, buf+j, 4);
memcpy (&b, buf+j+4, 4);
r_mem_copyendian ((ut8*)&x, buf+j, sizeof (x), !p->big_endian);
r_print_cursor (p, j, 1);
printfmt ("0x%08x%08x ", b, a); //n<<32, n&0xffffff);
printfmt ("0x%016"PFMT64x" ", x);
r_print_cursor (p, j, 0);
j += 7;
} else {
@ -875,8 +873,7 @@ R_API char * r_print_colorize_opcode (char *p, const char *reg, const char *num)
int i, j, k, is_mod, is_arg = 0;
ut32 c_reset = strlen (Color_RESET);
int is_jmp = p && (*p == 'j' || ((*p == 'c') && (p[1] == 'a')))? 1: 0;
ut32 opcode_sz = p && *p ? strlen (p)*10 + 1 : 0,
bytes_consumed = 0;
ut32 opcode_sz = p && *p ? strlen (p)*10 + 1 : 0;
char *o;
if (!p || !*p) return NULL;

View File

@ -104,7 +104,6 @@ int cdb_findnext(struct cdb *c, ut32 u, const char *key, unsigned int len) {
u = ((u>>8)%c->hslots)<<3;
c->kpos = c->hpos + u;
}
while (c->loop < c->hslots) {
if (!cdb_read (c, buf, 8, c->kpos))
return 0;

View File

@ -66,23 +66,23 @@ int cdb_make_addend(struct cdb_make *c, ut32 keylen, ut32 datalen, ut32 h) {
}
static int pack_kvlen(ut8 *buf, ut32 klen, ut32 vlen) {
if (klen>=0xff) return 0;
if (vlen>=0xffffff) return 0;
if (klen>0xff) return 0; // 0xff = 254 chars+trailing zero
if (vlen>0xffffff) return 0;
buf[0] = (ut8)klen;
buf[1] = (ut8)((vlen ) & 255);
buf[2] = (ut8)((vlen>>8 ) & 255);
buf[3] = (ut8)((vlen>>16) & 255);
buf[1] = (ut8)((vlen ) & 0xff);
buf[2] = (ut8)((vlen>>8 ) & 0xff);
buf[3] = (ut8)((vlen>>16) & 0xff);
return 1;
}
int cdb_make_addbegin(struct cdb_make *c,unsigned int keylen,unsigned int datalen) {
int cdb_make_addbegin(struct cdb_make *c, unsigned int keylen, unsigned int datalen) {
ut8 buf[KVLSZ];
if (!pack_kvlen (buf, keylen, datalen))
return 0;
return buffer_putalign (&c->b, (const char *)buf, KVLSZ);
}
int cdb_make_add(struct cdb_make *c,const char *key,unsigned int keylen,const char *data,unsigned int datalen) {
int cdb_make_add(struct cdb_make *c, const char *key, unsigned int keylen, const char *data, unsigned int datalen) {
if (!cdb_make_addbegin (c, keylen, datalen)) return 0;
if (!buffer_putalign (&c->b, key, keylen)) return 0;
if (!buffer_putalign (&c->b, data, datalen)) return 0;

View File

@ -44,6 +44,31 @@ SDB_API int sdb_json_num_get (Sdb *s, const char *k, const char *p, ut32 *cas) {
return 0;
}
static int findkey(Rangstr *rs) {
int i;
for (i = rs->f ; i>0; i--) {
if (rs->p[i] == '"') {
for (--i;i>0; i--) {
if (rs->p[i] == '"')
return i;
}
}
}
return -1;
}
static int isstring(const char *s) {
if (!strcmp (s, "true"))
return 0;
if (!strcmp (s, "false"))
return 0;
for (;*s;s++) {
if (*s<'0' || *s>'9')
return 1;
}
return 0;
}
// JSON only supports base16 numbers
SDB_API int sdb_json_num_set (Sdb *s, const char *k, const char *p, int v, ut32 cas) {
char *_str, str[64];
@ -51,6 +76,10 @@ SDB_API int sdb_json_num_set (Sdb *s, const char *k, const char *p, int v, ut32
return sdb_json_set (s, k, p, _str, cas);
}
SDB_API int sdb_json_unset (Sdb *s, const char *k, const char *p, ut32 cas) {
return sdb_json_set (s, k, p, NULL, cas);
}
SDB_API int sdb_json_set (Sdb *s, const char *k, const char *p, const char *v, ut32 cas) {
const char *beg[3];
const char *end[3];
@ -59,40 +88,111 @@ SDB_API int sdb_json_set (Sdb *s, const char *k, const char *p, const char *v, u
Rangstr rs;
ut32 c;
char *js = sdb_get (s, k, &c);
if (!js) return 0;
if (!js) {
char *b = malloc (strlen(k)+strlen (v)+8);
if (b) {
int is_str = isstring (v);
const char *q = is_str?"\"":"";
sprintf (b, "{\"%s\":%s%s%s}", p, q,v, q);
sdb_set (s, k, b, cas);
free (b);
free (js);
return 1;
}
return 0;
}
if (cas && c != cas) {
free (js);
return 0;
}
rs = json_get (js, p);
if (!rs.p) {
char *b = malloc (strlen (js)+strlen(k)+strlen (v)+5);
if (b) {
int is_str = isstring (v);
const char *q = is_str?"\"":"";
const char *e = ""; // XX: or comma
if (js[0] && js[1] != '}') {
e = ",";
}
sprintf (b, "{\"%s\":%s%s%s%s", p, q,v, q, e);
// TODO: verify ending }
strcat (b, js+1);
sdb_set (s, k, b, cas);
free (b);
free (js);
return 1;
}
// invalid json?
free (js);
return 0;
}
}
#define WLEN(x) (int)(size_t)(end[x]-beg[x])
beg[0] = js;
end[0] = rs.p + rs.f;
len[0] = WLEN (0);
beg[1] = v;
end[1] = v + strlen (v);
len[1] = WLEN (1);
if (*v) {
beg[1] = v;
end[1] = v + strlen (v);
len[1] = WLEN (1);
}
beg[2] = rs.p + rs.t;
end[2] = js + strlen (js);
len[2] = WLEN (2);
// TODO: accelerate with small buffer in stack for small jsons
str = malloc (len[0]+len[1]+len[2]+1);
idx = len[0];
memcpy (str, beg[0], idx);
l = len[1];
memcpy (str+idx, beg[1], l);
idx += len[1];
l = len[2];
memcpy (str+idx, beg[2], l);
str[idx+l] = 0;
if (*v) {
int is_str = isstring (v);
str = malloc (len[0]+len[1]+len[2]+1);
idx = len[0];
memcpy (str, beg[0], idx);
if (is_str) {
if (beg[2][0]!='"') {
str[idx]='"';
idx++;
}
} else {
if (beg[2][0]=='"') {
idx--;
}
}
l = len[1];
memcpy (str+idx, beg[1], l);
idx += len[1];
if (is_str) {
// TODO: add quotes
if (beg[2][0]!='"') {
str[idx]='"';
idx++;
}
} else {
if (beg[2][0]=='"') {
beg[2]++;
}
}
l = len[2];
memcpy (str+idx, beg[2], l);
str[idx+l] = 0;
} else {
// DELETE KEY
rs.f -= 2;
int kidx = findkey (&rs);
len[0] = R_MAX(1, kidx-1);
if (kidx==1){
if (beg[2][0]=='"')
beg[2]++;
beg[2]++;
}
str = malloc (len[0]+len[2]+1);
memcpy (str, beg[0], len[0]);
if (!*beg[2])
beg[2]--;
memcpy (str+len[0], beg[2], len[2]+1);
}
sdb_set (s, k, str, cas);
free (str);

View File

@ -192,6 +192,8 @@ next_quote:
root+len, ns);
} else eprintf ("TODO: Namespace too long\n");
}
if (bufset)
free (buf);
return out;
}
if (!strcmp (cmd, "**")) {
@ -200,11 +202,15 @@ next_quote:
ls_foreach (s->ns, it, ns) {
out_concat (ns->name);
}
if (bufset)
free (buf);
return out;
}
if (!strcmp (cmd, "*")) {
ForeachListUser user = { &out, encode };
sdb_foreach (s, foreach_list_cb, &user);
if (bufset)
free (buf);
return out;
}
}
@ -293,7 +299,8 @@ next_quote:
}
w = snprintf (buf, len, "%d", alength);
if (w<0 || (size_t)w>len) {
free (buf);
if (bufset)
free (buf);
buf = malloc (64);
bufset = 1;
snprintf (buf, 63, "%d", alength);

View File

@ -134,7 +134,7 @@ SDB_API const char *sdb_const_get (Sdb* s, const char *key, ut32 *cas) {
if (cas) *cas = 0;
if (!s||!key) return NULL;
keylen = strlen (key)+1;
hash = sdb_hash (key, 0); //keylen-1);
hash = sdb_hash (key, -1); //keylen-1);
/* search in memory */
kv = (SdbKv*)ht_lookup (s->ht, hash);
if (kv) {
@ -269,6 +269,8 @@ SDB_API void sdb_reset (Sdb* s) {
// TODO: too many allocs here. use slices
SDB_API SdbKv* sdb_kv_new (const char *k, const char *v) {
int vl = strlen (v)+1;
if (!sdb_check_key (k))
return NULL;
SdbKv *kv = R_NEW (SdbKv);
strncpy (kv->key, k, sizeof (kv->key)-1);
kv->value = malloc (vl);
@ -327,7 +329,7 @@ SDB_API int sdb_foreach (Sdb* s, SdbForeachCallback cb, void *user) {
SdbKv *kv;
sdb_dump_begin (s);
while (sdb_dump_dupnext (s, &k, &v)) {
ut32 hash = sdb_hash (k, 0);
ut32 hash = sdb_hash (k, -1);
SdbHashEntry *hte = ht_search (s->ht, hash);
if (hte) {
free (k);
@ -378,7 +380,7 @@ SDB_API int sdb_sync (Sdb* s) {
// TODO: use sdb_foreach here
sdb_dump_begin (s);
while (sdb_dump_dupnext (s, &k, &v)) {
ut32 hash = sdb_hash (k, 0);
ut32 hash = sdb_hash (k, -1);
SdbHashEntry *hte = ht_search (s->ht, hash);
if (hte) {
kv = (SdbKv*)hte->data;
@ -445,7 +447,7 @@ SDB_API int sdb_dump_dupnext (Sdb* s, char **key, char **value) {
return 0;
if (key) {
*key = 0;
if (klen>0) {
if (klen>0 && klen<0xff) {
*key = malloc (klen+1);
if (getbytes (s, *key, klen) == -1) {
free (*key);
@ -496,7 +498,7 @@ SDB_API int sdb_expire_set(Sdb* s, const char *key, ut64 expire) {
s->expire = parse_expire (expire);
return 1;
}
hash = sdb_hash (key, 0);
hash = sdb_hash (key, -1);
kv = (SdbKv*)ht_lookup (s->ht, hash);
if (kv) {
if (*kv->value) {
@ -525,7 +527,7 @@ SDB_API int sdb_expire_set(Sdb* s, const char *key, ut64 expire) {
SDB_API ut64 sdb_expire_get(Sdb* s, const char *key) {
SdbKv *kv;
ut32 hash = sdb_hash (key, 0);
ut32 hash = sdb_hash (key, -1);
kv = (SdbKv*)ht_lookup (s->ht, hash);
if (kv && *kv->value)
return kv->expire;

View File

@ -33,6 +33,7 @@ extern "C" {
#define SDB_OPTION_NOSTAMP 2
#define SDB_OPTION_FS 4
// This size implies trailing zero terminator, this is 254 chars + 0
#define SDB_KSZ 0xff
typedef struct sdb_kv {

View File

@ -7,6 +7,7 @@
SDB_API int sdb_check_value(const char *s) {
if (!s || *s=='$')
return 0;
// TODO: check value length
#if 0
for (; *s; s++) {
switch (*s) {
@ -22,21 +23,24 @@ SDB_API int sdb_check_key(const char *s) {
const char *special_chars = "\"+-=[]:$;";
if (!s || !*s)
return 0;
if (strlen (s)>=SDB_KSZ)
return 0;
for (; *s; s++)
if (strchr (special_chars, *s))
return 0;
return 1;
}
// assert sdb_hash("hi", 2) == sdb_hash("hi", 0)
SDB_API ut32 sdb_hash(const char *s, int len) {
ut32 h = CDB_HASHSTART;
if (len<1) {
while (*s)
h = (h+(h<<5))^*s++;
} else {
while (len--)
h = (h+(h<<5))^*s++;
if (s) {
if (len<0) {
while (*s)
h = (h+(h<<5))^*s++;
} else {
while (len--)
h = (h+(h<<5))^*s++;
}
}
return h;
}