From 10f2439c5d803402d13b863855b77f3aa893854d Mon Sep 17 00:00:00 2001 From: pancake Date: Thu, 10 Apr 2014 19:17:24 +0200 Subject: [PATCH] Update sdb and fix #777 - pxq and pxw honors cfg.big_endian --- doc/fortunes | 1 + libr/anal/fcn.c | 9 +++ libr/include/sdb/sdb.h | 1 + libr/util/print.c | 17 +++--- shlr/sdb/src/cdb.c | 1 - shlr/sdb/src/cdb_make.c | 14 ++--- shlr/sdb/src/json.c | 128 +++++++++++++++++++++++++++++++++++----- shlr/sdb/src/query.c | 9 ++- shlr/sdb/src/sdb.c | 14 +++-- shlr/sdb/src/sdb.h | 1 + shlr/sdb/src/util.c | 18 +++--- 11 files changed, 167 insertions(+), 46 deletions(-) diff --git a/doc/fortunes b/doc/fortunes index c38a7d4027..30bc940794 100644 --- a/doc/fortunes +++ b/doc/fortunes @@ -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 diff --git a/libr/anal/fcn.c b/libr/anal/fcn.c index a8c64c466f..578ab16c7a 100644 --- a/libr/anal/fcn.c +++ b/libr/anal/fcn.c @@ -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.=name,size,type + fcn..bbs + fcn.name.= +#endif + sdb_set (DB, "fcn.0x080", " #endif r_list_append (anal->fcns, fcn); return R_TRUE; diff --git a/libr/include/sdb/sdb.h b/libr/include/sdb/sdb.h index 536feefca0..d39b729cc2 100644 --- a/libr/include/sdb/sdb.h +++ b/libr/include/sdb/sdb.h @@ -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 { diff --git a/libr/util/print.c b/libr/util/print.c index edbd8a693c..61cbb8418b 100644 --- a/libr/util/print.c +++ b/libr/util/print.c @@ -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; diff --git a/shlr/sdb/src/cdb.c b/shlr/sdb/src/cdb.c index f58b71a3e7..e22fd911fb 100644 --- a/shlr/sdb/src/cdb.c +++ b/shlr/sdb/src/cdb.c @@ -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; diff --git a/shlr/sdb/src/cdb_make.c b/shlr/sdb/src/cdb_make.c index bf4548e618..4c429564f4 100644 --- a/shlr/sdb/src/cdb_make.c +++ b/shlr/sdb/src/cdb_make.c @@ -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; diff --git a/shlr/sdb/src/json.c b/shlr/sdb/src/json.c index 4a46d883ee..6b3038cfdc 100644 --- a/shlr/sdb/src/json.c +++ b/shlr/sdb/src/json.c @@ -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); diff --git a/shlr/sdb/src/query.c b/shlr/sdb/src/query.c index 0f9f591cca..2bfefb9e9d 100644 --- a/shlr/sdb/src/query.c +++ b/shlr/sdb/src/query.c @@ -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); diff --git a/shlr/sdb/src/sdb.c b/shlr/sdb/src/sdb.c index 89a46397cc..4465679a22 100644 --- a/shlr/sdb/src/sdb.c +++ b/shlr/sdb/src/sdb.c @@ -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; diff --git a/shlr/sdb/src/sdb.h b/shlr/sdb/src/sdb.h index 536feefca0..d39b729cc2 100644 --- a/shlr/sdb/src/sdb.h +++ b/shlr/sdb/src/sdb.h @@ -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 { diff --git a/shlr/sdb/src/util.c b/shlr/sdb/src/util.c index a510a8104c..355445bc5f 100644 --- a/shlr/sdb/src/util.c +++ b/shlr/sdb/src/util.c @@ -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; }