diff --git a/libr/anal/anal.c b/libr/anal/anal.c index 79669f9bd0..7154f7efe4 100644 --- a/libr/anal/anal.c +++ b/libr/anal/anal.c @@ -55,7 +55,7 @@ R_API RAnal *r_anal_new() { anal->sdb_locals = sdb_new (NULL, NULL, 0); anal->sdb_xrefs = NULL; anal->sdb_types = sdb_new (NULL, NULL, 0); - anal->sdb_meta = NULL; // TODO : implement sdb_meta + anal->sdb_meta = sdb_new (NULL, NULL, 0); r_meta_init (anal); anal->printf = (PrintfCallback) printf; r_anal_type_init (anal); diff --git a/libr/anal/meta.c b/libr/anal/meta.c index 232cfc71ab..6396d5dec0 100644 --- a/libr/anal/meta.c +++ b/libr/anal/meta.c @@ -1,33 +1,99 @@ /* radare - LGPL - Copyright 2008-2014 - nibble, pancake */ -// TODO: Use SDB - +// TODO: rename to r_anal_meta_get() ?? +#define USE_ANAL_SDB 1 #include #include +#if USE_ANAL_SDB +#define META_RANGE_BASE(x) ((x)>>12) +#define META_RANGE_SIZE 0xfff + +static char *meta_inrange_get (RAnal *a, ut64 addr, int size) { +#undef DB +#define DB a->sdb_meta + char key[64]; + ut64 base, base2; + base = META_RANGE_BASE (addr); + base2 = META_RANGE_BASE (addr+size); + // return string array of all the offsets where there are stuff + for (; basemeta = NULL; +#else a->meta = r_list_new (); a->meta->free = r_meta_item_free; +#endif } R_API void r_meta_fini(RAnal *a) { +#if !USE_ANAL_SDB r_list_free (a->meta); +#endif } -R_API int r_meta_count(RAnal *m, int type, ut64 from, ut64 to) { - RAnalMetaItem *d; - RListIter *iter; - int count = 0; - - r_list_foreach (m->meta, iter, d) { - if (d->type == type || type == R_META_TYPE_ANY) - if (from >= d->from && d->to < to) - count++; - } - return count; -} - +// TODO: Add APIs to resize meta? nope, just del and add R_API int r_meta_set_string(RAnal *m, int type, ut64 addr, const char *s) { +#if USE_ANAL_SDB +#undef DB +#define DB m->sdb_meta + char key[100], val[2048], *e_str; + int ret; + ut64 size; + snprintf (key, sizeof (key)-1, "meta.%c", type); + sdb_array_add_num (DB, key, -1, addr, 0); + + snprintf (key, sizeof (key)-1, "meta.%c.0x%"PFMT64x, type, addr); + size = sdb_array_get_num (DB, key, 0, 0); + if (!size) { + size = strlen (s); + meta_inrange_add (m, addr, size); + ret = R_TRUE; + } else ret = R_FALSE; + e_str = sdb_encode ((const void*)s, 0); + snprintf (val, sizeof (val)-1, "%d,%s", (int)size, e_str); + sdb_set (DB, key, val, 0); + free ((void*)e_str); + return ret; +#else RAnalMetaItem *mi = r_meta_find (m, addr, type, R_META_WHERE_HERE); if (mi) { free (mi->str); @@ -36,9 +102,24 @@ R_API int r_meta_set_string(RAnal *m, int type, ut64 addr, const char *s) { } r_meta_add (m, type, addr, addr+1, s); return R_FALSE; +#endif } R_API char *r_meta_get_string(RAnal *m, int type, ut64 addr) { +#if USE_ANAL_SDB +#undef DB +#define DB m->sdb_meta + char key[100]; + const char *k, *p; + snprintf (key, sizeof (key)-1, "meta.%c.0x%"PFMT64x, 'C', addr); + k = sdb_const_get (DB, key, NULL); + if (!k) return NULL; + p = strchr (k, SDB_RS); + if (!p) return NULL; + k = p+1; +// TODO : comment append has been deprecated + return (char *)sdb_decode (k, NULL); +#else char *str = NULL; RListIter *iter; RAnalMetaItem *d; @@ -70,9 +151,48 @@ R_API char *r_meta_get_string(RAnal *m, int type, ut64 addr) { } } return str; +#endif } -R_API int r_meta_del(RAnal *a, int type, ut64 from, ut64 size, const char *str) { +R_API int r_meta_del(RAnal *a, int type, ut64 addr, ut64 size, const char *str) { +#if USE_ANAL_SDB +#undef DB +#define DB a->sdb_meta + int i, nxt; + char key[100], key2[100], *dtr, *s, *p; + const char *ptr; + if (size == UT64_MAX) { + // FULL CLEANUP + // XXX: this thing ignores the type + if (type == R_META_TYPE_ANY) { + sdb_reset (DB); + } else { + snprintf (key, sizeof (key)-1, "meta.%c", type); + dtr = sdb_get (DB, key, 0); + for (p = dtr; p; p = s) { + s = sdb_array_string (p, &nxt); + snprintf (key, sizeof (key)-1, "meta.%c.0x%"PFMT64x, + type, sdb_atoi (s)); + eprintf ("--> %s\n", key); + sdb_unset (DB, key, 0); + if (!nxt) break; + } + free (dtr); + } + return R_FALSE; + } + meta_inrange_del (a, addr, size); + snprintf (key, sizeof (key)-1, "meta.0x%"PFMT64x, addr); + ptr = sdb_const_get (DB, key, 0); + for (i=0; ptr[i]; i++) { + if (ptr[i] != SDB_RS) { + snprintf (key2, sizeof (key2)-1, "meta.%c.0x%"PFMT64x, ptr[i], addr); + sdb_unset (DB, key2, 0); + } + } + sdb_unset (DB, key, 0); + return R_FALSE; +#else int ret = 0; RListIter *iter, *iter_tmp; RAnalMetaItem *d; @@ -81,7 +201,7 @@ R_API int r_meta_del(RAnal *a, int type, ut64 from, ut64 size, const char *str) if (d->type == type || type == R_META_TYPE_ANY) { if (str && d->str && !strstr (d->str, str)) continue; - if (size==UT64_MAX || (from+size >= d->from && from <= d->to-size)) { + if (size==UT64_MAX || (addr+size >= d->from && addr <= d->to-size)) { free (d->str); r_list_delete (a->meta, iter); ret++; @@ -89,13 +209,16 @@ R_API int r_meta_del(RAnal *a, int type, ut64 from, ut64 size, const char *str) } } return ret; +#endif } R_API int r_meta_cleanup(RAnal *a, ut64 from, ut64 to) { +#if USE_ANAL_SDB + eprintf ("TODO: Implement r_meta_cleanup for SDB\n"); +#else RAnalMetaItem *d; RListIter *iter, next; int ret = R_FALSE; - if (from == 0LL && to == UT64_MAX) { RList *m2 = a->meta; r_meta_init (a); @@ -143,6 +266,7 @@ R_API int r_meta_cleanup(RAnal *a, ut64 from, ut64 to) { iter = &next; } return ret; +#endif } R_API void r_meta_item_free(void *_item) { @@ -157,6 +281,22 @@ R_API RAnalMetaItem *r_meta_item_new(int type) { return mi; } +#if USE_ANAL_SDB +// DEPRECATED FUNCTIONS FTW +#else + +R_API int r_meta_count(RAnal *m, int type, ut64 from, ut64 to) { + RAnalMetaItem *d; + RListIter *iter; + int count = 0; + + r_list_foreach (m->meta, iter, d) { + if (d->type == type || type == R_META_TYPE_ANY) + if (from >= d->from && d->to < to) + count++; + } + return count; +} // TODO: This is ultraslow. must accelerate with hashtables R_API int r_meta_comment_check (RAnal *m, const char *s, ut64 addr) { RAnalMetaItem *d; @@ -168,11 +308,34 @@ R_API int r_meta_comment_check (RAnal *m, const char *s, ut64 addr) { if (!strcmp (s, d->str)) return R_TRUE; } - return R_FALSE; } +#endif R_API int r_meta_add(RAnal *m, int type, ut64 from, ut64 to, const char *str) { +#if USE_ANAL_SDB +#define DB m->sdb_meta + char *e_str, key[100], val[2048]; + if (from>=to) + return R_FALSE; + /* set entry */ + e_str = sdb_encode ((const void*)str, 0); + snprintf (key, sizeof (key)-1, "meta.%c.0x%"PFMT64x, type, from); + snprintf (val, sizeof (val)-1, "%d,%s", (int)(to-from), e_str); + sdb_set (DB, key, val, 0); + free (e_str); + + /* set type index */ + snprintf (key, sizeof (key)-1, "meta.0x%"PFMT64x, from); + snprintf (val, sizeof (val)-1, "%c", type); + sdb_array_add (DB, key, -1, val, 0); + + /* set type index */ + snprintf (key, sizeof (key)-1, "meta.%c", type); + sdb_array_add_num (DB, key, -1, from, 0); + + return R_TRUE; +#else RAnalMetaItem *mi; if (totype == R_META_TYPE_FORMAT) mi->size = r_print_format_length (mi->str); return R_TRUE; +#endif } /* snippet from data.c */ R_API RAnalMetaItem *r_meta_find(RAnal *m, ut64 off, int type, int where) { +#if USE_ANAL_SDB + static RAnalMetaItem it = {0}; + // XXX: return allocated item? wtf + if (where != R_META_WHERE_HERE) { + eprintf ("THIS WAS NOT SUPOSED TO HAPPEN\n"); + return NULL; + } + //char *range = get_in_range (off); + if (type == R_META_TYPE_ANY) { + char key [100]; + snprintf (key, sizeof (key)-1, "meta.0x%"PFMT64x, off); + } else { + // snprintf (key, sizeof (key)-1, "meta. + } + return ⁢ +#else RAnalMetaItem *d, *it = NULL; RListIter *iter; r_list_foreach (m->meta, iter, d) { @@ -236,6 +416,7 @@ R_API RAnalMetaItem *r_meta_find(RAnal *m, ut64 off, int type, int where) { } } return it; +#endif } #if 0 @@ -281,23 +462,6 @@ R_API const char *r_meta_type_to_string(int type) { return "(...)"; } -#if 0 -#include -struct r_range_t *r_meta_ranges(RAnal *m) -{ - struct r_range_t *r; - struct list_head *pos; - - r = r_range_new(); - list_for_each(pos, &m->meta) { - struct r_meta_item_t *d = (struct r_meta_item_t *) - list_entry(pos, struct r_meta_item_t, list); - r_range_add(r, d->from, d->to, 1); //d->type); - } - return r; -} -#endif - static void printmetaitem(RAnal *m, RAnalMetaItem *d, int rad) { char *pstr, *str = r_str_escape (d->str); if (str) { @@ -332,8 +496,42 @@ static void printmetaitem(RAnal *m, RAnalMetaItem *d, int rad) { } } +#if USE_ANAL_SDB +typedef struct { + RAnal *anal; + int type; + int rad; +} RAnalMetaUserItem; + +static int meta_print_item(void *user, const char *k, const char *v) { + RAnalMetaUserItem *ui = user; + RAnalMetaItem it; + if (strlen (k)<8) + return R_FALSE; + if (k[6]!='.') + return R_FALSE; + it.type = k[5]; + it.size = sdb_atoi (v); + it.from = sdb_atoi (k+7); + it.to = it.from + it.size; + it.str = strchr (v, ','); + if (it.str) + it.str = (char *)sdb_decode ((const char*)it.str+1, 0); + printmetaitem (ui->anal, &it, ui->rad); + free (it.str); + return R_TRUE; +} +#endif + // TODO: Deprecate R_API int r_meta_list(RAnal *m, int type, int rad) { +#if USE_ANAL_SDB +#define DB m->sdb_meta + RAnalMetaUserItem ui = { m, type, rad }; +// XXX: doesnt works well on sync + sdb_foreach (DB, meta_print_item, &ui); + return 0; +#else int count = 0; RListIter *iter; RAnalMetaItem *d; @@ -347,23 +545,17 @@ R_API int r_meta_list(RAnal *m, int type, int rad) { } if (rad=='j') m->printf ("]\n"); return count; +#endif } R_API char *r_anal_meta_bar (RAnal *anal, ut64 from, ut64 to, int blocks) { int i, n, blocksize; char *res; ut64 f, t; - if (blocks<1 || from > to) return NULL; -#if 0 - if (from == to && from == 0) { - // autodetect min and max here - // from = - } -#endif blocksize = (to-from)/blocks; - res = malloc (blocks*4); //blocksize*5);// use realloc here + res = malloc (blocks*4); for (i=0; i< blocks; i++) { f = from + (blocksize*i); t = f+blocksize; diff --git a/libr/include/sdb/sdb.h b/libr/include/sdb/sdb.h index f7a97da434..75703c9ad9 100644 --- a/libr/include/sdb/sdb.h +++ b/libr/include/sdb/sdb.h @@ -20,6 +20,7 @@ extern "C" { #define SDB_RS ',' #define SDB_SS "," #define SDB_MAX_PATH 256 +#define SDB_NUM_BASE 10 #define SDB_OPTION_NONE 0 #define SDB_OPTION_ALL 0xff @@ -151,6 +152,7 @@ void sdb_ns_sync (Sdb* s); // array int sdb_array_exists (Sdb* s, const char *key, const char *val); +SDB_API int sdb_array_exists_num(Sdb *s, const char *key, ut64 val); int sdb_array_add (Sdb* s, const char *key, int idx, const char *val, ut32 cas); int sdb_array_add_num (Sdb* s, const char *key, int idx, ut64 val, ut32 cas); int sdb_array_set (Sdb* s, const char *key, int idx, const char *val, ut32 cas); @@ -188,6 +190,12 @@ int sdb_num_base (const char *s); int sdb_bool_set(Sdb *db, const char *str, int v, ut32 cas); int sdb_bool_get(Sdb *db, const char *str, ut32 *cas); +// base64 +ut8 *sdb_decode (const char *in, int *len); +SDB_API char *sdb_encode(const ut8 *bin, int len); +SDB_API void sdb_encode_raw(char *bout, const ut8 *bin, int len); +SDB_API int sdb_decode_raw(ut8 *bout, const char *bin, int len); + #ifdef __cplusplus } #endif diff --git a/libr/io/p/io_rap.c b/libr/io/p/io_rap.c index 0b7e0d42bc..55e392fdb6 100644 --- a/libr/io/p/io_rap.c +++ b/libr/io/p/io_rap.c @@ -206,7 +206,6 @@ static RIODesc *rap__open(struct r_io_t *io, const char *pathname, int rw, int m } r_mem_copyendian ((ut8 *)&i, (ut8*)buf+1, 4, ENDIAN); if (i>0) eprintf ("ok\n"); - #if 0 /* Read meta info */ r_socket_read (rap_fd, (ut8 *)&buf, 4); @@ -272,7 +271,7 @@ static int rap__system(RIO *io, RIODesc *fd, const char *command) { if (i == -1) return -1; ret = 0; - ptr = (char *)malloc (i); + ptr = (char *)malloc (i+1); if (ptr) { int ir, tr = 0; do { diff --git a/shlr/sdb/src/Makefile b/shlr/sdb/src/Makefile index 54fbd5a460..694b7b2a7a 100644 --- a/shlr/sdb/src/Makefile +++ b/shlr/sdb/src/Makefile @@ -1,7 +1,7 @@ include ../config.mk CFLAGS+= -g -ggdb -OBJ=cdb.o buffer.o cdb_make.o ls.o ht.o sdb.o num.o +OBJ=cdb.o buffer.o cdb_make.o ls.o ht.o sdb.o num.o base64.o OBJ+=json.o ns.o lock.o util.o disk.o query.o array.o SOBJ=$(subst .o,._o,${OBJ}) diff --git a/shlr/sdb/src/array.c b/shlr/sdb/src/array.c index 8762fe754b..4433bbbd11 100644 --- a/shlr/sdb/src/array.c +++ b/shlr/sdb/src/array.c @@ -81,7 +81,8 @@ SDB_API char *sdb_array_get(Sdb *s, const char *key, int idx, ut32 *cas) { SDB_API int sdb_array_ins_num(Sdb *s, const char *key, int idx, ut64 val, ut32 cas) { char valstr[64]; - return sdb_array_ins (s, key, idx, sdb_itoa (val, valstr, 10), cas); + return sdb_array_ins (s, key, idx, + sdb_itoa (val, valstr, SDB_NUM_BASE), cas); } // TODO: done, but there's room for improvement @@ -128,11 +129,12 @@ SDB_API int sdb_array_ins(Sdb *s, const char *key, int idx, const char *val, ut3 SDB_API int sdb_array_set_num(Sdb *s, const char *key, int idx, ut64 val, ut32 cas) { char valstr[64]; - return sdb_array_set (s, key, idx, sdb_itoa (val, valstr, 10), cas); + return sdb_array_set (s, key, idx, + sdb_itoa (val, valstr, SDB_NUM_BASE), cas); } SDB_API int sdb_array_add_num(Sdb *s, const char *key, int idx, ut64 val, ut32 cas) { - char valstr[64], *vs = sdb_itoa (val, valstr, 10); + char valstr[64], *vs = sdb_itoa (val, valstr, SDB_NUM_BASE); if (sdb_array_exists (s, key, vs)) return 0; return sdb_array_add (s, key, idx, vs, cas); @@ -280,6 +282,12 @@ SDB_API const char *sdb_array_index(const char *str, int idx) { return NULL; } +SDB_API int sdb_array_exists_num(Sdb *s, const char *key, ut64 num) { + char val[64]; + char *nval = sdb_itoa (num, val, SDB_NUM_BASE); + return sdb_array_exists (s, key, nval); +} + SDB_API int sdb_array_exists(Sdb *s, const char *key, const char *val) { int found = 0, hasnext = 1; char *list = sdb_get (s, key, 0); diff --git a/shlr/sdb/src/base64.c b/shlr/sdb/src/base64.c new file mode 100644 index 0000000000..b8e6dfde46 --- /dev/null +++ b/shlr/sdb/src/base64.c @@ -0,0 +1,85 @@ +/* base64 enc/dec - LGPLv3 - Copyright 2011-2014 - pancake */ + +#include +#include +#include +#include +#include "sdb.h" + +#define SZ 1024 +static const char cb64[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +static const char cd64[]="|$$$}rstuvwxyz{$$$$$$$>?@ABCDEFGHIJKLMNOPQRSTUVW$$$$$$XYZ[\\]^_`abcdefghijklmnopq"; + +static void b64_encode(const ut8 in[3], char out[4], int len) { + out[0] = cb64[ in[0] >> 2 ]; + out[1] = cb64[ ((in[0] & 0x03) << 4) | ((in[1] & 0xf0) >> 4) ]; + out[2] = (len > 1 ? cb64[ ((in[1] & 0x0f) << 2) | ((in[2] & 0xc0) >> 6) ] : '='); + out[3] = (len > 2 ? cb64[ in[2] & 0x3f ] : '='); +} + +static int b64_decode(const char in[4], ut8 out[3]) { + ut8 len = 3, i, v[4] = {0}; + for (i=0; i<4; i++) { + if (in[i]<43 || in[i]>122) + return -1; + v[i] = cd64[in[i]-43]; + if (v[i]=='$') { + len = i-1; + break; + } + v[i]-=62; + } + out[0] = v[0] << 2 | v[1] >> 4; + out[1] = v[1] << 4 | v[2] >> 2; + out[2] = ((v[2] << 6) & 0xc0) | v[3]; + return len; +} + +SDB_API void sdb_encode_raw(char *bout, const ut8 *bin, int len) { + int in, out; + for (in=out=0; in3?3:len-in); + bout[out] = 0; +} + +SDB_API int sdb_decode_raw(ut8 *bout, const char *bin, int len) { + int in, out, ret; + for (in=out=0; inoptions & SDB_OPTION_FS) { if (!sdb_query_file (s, cmd+1)) { fprintf (stderr, "sdb: cannot open '%s'\n", cmd+1); - goto failure; + goto fail; } } else { fprintf (stderr, "sdb: filesystem access disabled in config\n"); @@ -205,15 +213,30 @@ next_quote: /* [+3]foo=bla */ if (i<0) { char *tmp = sdb_array_get (s, p, -i, NULL); - ok = 0; - out_concat (tmp); - sdb_array_del (s, p, -i, 0); - free (tmp); + if (tmp) { + if (encode) { + char *newtmp = (void*)sdb_decode (tmp, NULL); + if (!newtmp) + goto fail; + free (tmp); + tmp = newtmp; + } + ok = 0; + out_concat (tmp); + sdb_array_del (s, p, -i, 0); + free (tmp); + } else goto fail; } else { + if (encode) + val = sdb_encode ((const ut8*)val, 0); ok = cmd[1]? ((cmd[1]=='+')? sdb_array_ins (s, p, i, val, 0): sdb_array_set (s, p, i, val, 0) ): sdb_array_del (s, p, i, 0); + if (encode) { + free ((void*)val); + val = NULL; + } } if (ok) *buf = 0; else buf = NULL; @@ -244,17 +267,19 @@ next_quote: } else { if (eq) { /* [3]foo=bla */ - char *q, *sval = strdup (val); - // TODO: define new printable separator character - for (q=sval; *q; q++) if (*q==',') *q = SDB_RS; + char *sval = (char*)val; + if (encode) { + sval = sdb_encode ((const ut8*)val, 0); + } if (cmd[1]) { int idx = atoi (cmd+1); - ok = sdb_array_set (s, p, idx, val, 0); + ok = sdb_array_set (s, p, idx, sval, 0); // TODO: handle when idx > sdb_alen } else { ok = sdb_set (s, p, sval, 0); } - free (sval); + if (encode) + free (sval); if (ok) { *buf = 0; return buf; @@ -265,9 +290,16 @@ next_quote: size_t wl; if (cmd[1]) { i = atoi (cmd+1); - tmp = sdb_array_get (s, p, i, NULL); - out_concat (tmp); - free (tmp); + buf = sdb_array_get (s, p, i, NULL); + bufset = 1; + if (encode) { + char *newbuf = (void*)sdb_decode (buf, NULL); + if (newbuf) { + free (buf); + buf = newbuf; + } + } + out_concat (buf); } else { if (!sval) return NULL; wl = strlen (sval); @@ -281,6 +313,13 @@ next_quote: else buf[i] = sval[i]; } buf[i] = 0; + if (encode) { + char *newbuf = (void*)sdb_decode (buf, NULL); + if (newbuf) { + free (buf); + buf = newbuf; + } + } out_concat (buf); } } @@ -289,13 +328,19 @@ next_quote: if (eq) { // 1 0 kvpath=value // 1 1 kvpath:jspath=value + if (encode) + val = sdb_encode ((const ut8*)val, 0); if (json>eq) json = NULL; if (json) { *json++ = 0; ok = sdb_json_set (s, cmd, json, val, 0); } else ok = sdb_set (s, cmd, val, 0); + if (encode) { + free ((void*)val); + val = NULL; + } if (!ok) - goto failure; + goto fail; } else { // 0 1 kvpath?jspath // 0 0 kvpath @@ -303,13 +348,24 @@ next_quote: *json++ = 0; // TODO: not optimized to reuse 'buf' if ((tmp = sdb_json_get (s, cmd, json, 0))) { + if (encode) { + char *newtmp = (void*)sdb_decode (tmp, NULL); + if (!newtmp) + goto fail; + free (tmp); + tmp = newtmp; + } out_concat (tmp); free (tmp); } } else { // sdbget if ((q = sdb_const_get (s, cmd, 0))) { + if (encode) + q = (void*)sdb_decode (q, NULL); out_concat (q); + if (encode) + free ((void*)q); } } } @@ -324,7 +380,7 @@ next_quote: goto repeat; } if (eq) *--eq = '='; -failure: +fail: if (bufset) free (buf); return out; diff --git a/shlr/sdb/src/sdb.h b/shlr/sdb/src/sdb.h index f7a97da434..75703c9ad9 100644 --- a/shlr/sdb/src/sdb.h +++ b/shlr/sdb/src/sdb.h @@ -20,6 +20,7 @@ extern "C" { #define SDB_RS ',' #define SDB_SS "," #define SDB_MAX_PATH 256 +#define SDB_NUM_BASE 10 #define SDB_OPTION_NONE 0 #define SDB_OPTION_ALL 0xff @@ -151,6 +152,7 @@ void sdb_ns_sync (Sdb* s); // array int sdb_array_exists (Sdb* s, const char *key, const char *val); +SDB_API int sdb_array_exists_num(Sdb *s, const char *key, ut64 val); int sdb_array_add (Sdb* s, const char *key, int idx, const char *val, ut32 cas); int sdb_array_add_num (Sdb* s, const char *key, int idx, ut64 val, ut32 cas); int sdb_array_set (Sdb* s, const char *key, int idx, const char *val, ut32 cas); @@ -188,6 +190,12 @@ int sdb_num_base (const char *s); int sdb_bool_set(Sdb *db, const char *str, int v, ut32 cas); int sdb_bool_get(Sdb *db, const char *str, ut32 *cas); +// base64 +ut8 *sdb_decode (const char *in, int *len); +SDB_API char *sdb_encode(const ut8 *bin, int len); +SDB_API void sdb_encode_raw(char *bout, const ut8 *bin, int len); +SDB_API int sdb_decode_raw(ut8 *bout, const char *bin, int len); + #ifdef __cplusplus } #endif diff --git a/shlr/sdb/src/util.c b/shlr/sdb/src/util.c index f1c611d2da..53a5cc103b 100644 --- a/shlr/sdb/src/util.c +++ b/shlr/sdb/src/util.c @@ -126,7 +126,7 @@ SDB_API int sdb_isnum (const char *s) { } SDB_API int sdb_num_base (const char *s) { - if (!s) return 10; + if (!s) return SDB_NUM_BASE; if (!strncmp (s, "0x", 2)) return 16; if (*s=='0' && s[1]) return 8;