Skip to content

Commit

Permalink
Update sdb, adds support for SdbFmt, fixes segfault in sdb_encode
Browse files Browse the repository at this point in the history
  • Loading branch information
radare committed Mar 5, 2014
1 parent c7772d9 commit b48153d
Show file tree
Hide file tree
Showing 8 changed files with 192 additions and 45 deletions.
17 changes: 14 additions & 3 deletions libr/include/sdb/sdb.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ extern "C" {
#include "cdb_make.h"
#include "sdb-version.h"

#undef R_MAX
#define R_MAX(x,y) (((x)>(y))?(x):(y))
#undef r_offsetof
#define r_offsetof(type, member) ((unsigned long) &((type*)0)->member)

//#define SDB_RS '\x1e'
#define SDB_RS ','
#define SDB_SS ","
Expand Down Expand Up @@ -194,9 +199,15 @@ 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);
char *sdb_encode(const ut8 *bin, int len);
void sdb_encode_raw(char *bout, const ut8 *bin, int len);
int sdb_decode_raw(ut8 *bout, const char *bin, int len);

// binfmt
int sdb_fmt_init (void *p, const char *fmt);
void sdb_fmt_free (void *p, const char *fmt);
int sdb_fmt_tobin(const char *_str, const char *fmt, void *stru);
char *sdb_fmt_tostr(void *stru, const char *fmt);

#ifdef __cplusplus
}
Expand Down
1 change: 1 addition & 0 deletions shlr/sdb/config.mk
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ CFLAGS+=$(shell gcc -v 2>&1 | grep -q LLVM && echo '-Wno-initializer-overrides')
CFLAGS+=-Wall
#CFLAGS+=-O3
#CFLAGS+=-ggdb -g -Wall -O0
CFLAGS+=-g

HAVE_VALA=#$(shell valac --version 2> /dev/null)
# This is hacky
Expand Down
2 changes: 1 addition & 1 deletion shlr/sdb/src/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ include ../config.mk

CFLAGS+= -g -ggdb
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
OBJ+=json.o ns.o lock.o util.o disk.o query.o array.o fmt.o

SOBJ=$(subst .o,._o,${OBJ})

Expand Down
1 change: 1 addition & 0 deletions shlr/sdb/src/array.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ SDB_API const char *sdb_array_next(const char *str) {
return str+strlen (str)+1;
}

// TODO: nxt can be a pointer to the string, not a bool and we can get ird of array_next()
SDB_API char *sdb_array_string(char *str, int *hasnext) {
int nxt = 0;
char *p = strchr (str, SDB_RS);
Expand Down
6 changes: 4 additions & 2 deletions shlr/sdb/src/base64.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ SDB_API char *sdb_encode(const ut8 *bin, int len) {
len = strlen ((const char *)bin)+1;
if (len==0)
return strdup ("");
out = malloc (len+8);
out = malloc (len*2);
if (!out)
return NULL;
memset (out, 0, len+8);
Expand All @@ -70,7 +70,9 @@ SDB_API char *sdb_encode(const ut8 *bin, int len) {
SDB_API ut8 *sdb_decode (const char *in, int *len) {
ut8 *out;
int olen, ilen = strlen (in);
out = malloc (ilen+8);
if (ilen<1)
return NULL;
out = malloc (ilen*2);
if (!out)
return NULL;
memset (out, 0, ilen+8);
Expand Down
135 changes: 135 additions & 0 deletions shlr/sdb/src/fmt.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
/* sdb - LGPLv3 - Copyright 2014 - pancake */

#include "sdb.h"

// SLOW CONCAT
#define out_concat(x) if (x) { \
char *o =(void*)realloc((void*)out, 2+strlen(x)+(out?strlen(out):0)); \
if (o) { if (*o) strcat (o, ","); out=o; strcat (o, x); } \
}

SDB_API char *sdb_fmt_tostr(void *stru, const char *fmt) {
const char *num;
char *out = NULL;
ut8 *p = stru;
char buf[128];
int n, len = 0;

for (; *fmt; fmt++) {
n = 4;
switch (*fmt) {
case 'b':
num = sdb_itoa ((ut64)*((ut8*)(p+len)), buf, 10);
out_concat (num);
break;
case 'h':
num = sdb_itoa ((ut64)*((short*)(p+len)), buf, 10);
out_concat (num);
break;
case 'd':
num = sdb_itoa ((ut64)*((int*)(p+len)), buf, 10);
out_concat (num);
break;
case 'q':
num = sdb_itoa (*((ut64*)(p+len)), buf, 10);
out_concat (num);
n = 8;
break;
case 's':
{
char *e_str = sdb_encode ((const ut8*)*((char**)(p+len)), 0);
out_concat (e_str);
free (e_str);
}
break;
case 'p':
num = sdb_itoa ((ut64)*((size_t*)(p+len)), buf, 16);
out_concat (num);
n = sizeof (size_t);
break;
}
len += R_MAX (sizeof (void*), n); // align
}
return out;
}

// TODO: return false if array length != fmt length
SDB_API int sdb_fmt_tobin(const char *_str, const char *fmt, void *stru) {
int nxt, n, idx = 0;
char *str, *ptr, *word;
str = ptr = strdup (_str);
for (; *fmt; fmt++) {
word = sdb_array_string (ptr, &nxt);
if (!word || !*word)
break;
n = 4; // ALIGN
switch (*fmt) {
case 'q': *((ut64*)(stru + idx)) = sdb_atoi (word); n=8; break;
case 'h': *((short*)(stru + idx)) = (short)sdb_atoi (word); break;
case 'd': *((int*)(stru + idx)) = (int)sdb_atoi (word); break;
case 's':
{
ut8 *e_str = sdb_decode (word, 0);
if (!e_str) e_str = (ut8*)word;
*((char**)(stru + idx)) = (char*)e_str;
}
break;
case 'p': *((void**)(stru + idx)) = (void*)(size_t)sdb_atoi (word);
break;
default: eprintf ("WTF\n"); break;
}
idx += R_MAX(sizeof (void*), n); // align
if (!nxt)
break;
ptr = (char*)sdb_array_next (word);
}
return 1;
}

SDB_API void sdb_fmt_free (void *p, const char *fmt) {
// TODO: free() 's' and memset the rest
}

SDB_API int sdb_fmt_init (void *p, const char *fmt) {
int len = 0;
for (; *fmt; fmt++) {
switch (*fmt) {
case 'b': len += sizeof (ut8); break; // 1
case 'h': len += sizeof (short); break; // 2
case 'd': len += sizeof (ut32); break; // 4
case 'q': len += sizeof (ut64); break; // 8
case 's': len += sizeof (char*); break; // void*
case 'p': len += sizeof (char*); break; // void *
}
}
if (p) memset (p, 0, len);
return len;
}


#if 0
main() {
#define STRUCT_PERSON_FORMAT "ds"
#define STRUCT_PERSON_SIZE sizeof (struct Person)
typedef struct person {
int foo;
char *str;
ut64 fin;
int end;
} Person;

Person p;

sdb_fmt_init (&p, "dsqd");
sdb_fmt_tobin ("123,bar,321,1", "dsqd", &p);
eprintf ("--> %d,%s\n", p.foo, p.str);
eprintf ("--> %lld,%d\n", p.fin, p.end);

{
char *o = sdb_fmt_tostr (&p, "dsqd");
eprintf ("== %s\n", o);
free (o);
}
sdb_fmt_free (&p, "ds");
}
#endif
17 changes: 14 additions & 3 deletions shlr/sdb/src/sdb.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ extern "C" {
#include "cdb_make.h"
#include "sdb-version.h"

#undef R_MAX
#define R_MAX(x,y) (((x)>(y))?(x):(y))
#undef r_offsetof
#define r_offsetof(type, member) ((unsigned long) &((type*)0)->member)

//#define SDB_RS '\x1e'
#define SDB_RS ','
#define SDB_SS ","
Expand Down Expand Up @@ -194,9 +199,15 @@ 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);
char *sdb_encode(const ut8 *bin, int len);
void sdb_encode_raw(char *bout, const ut8 *bin, int len);
int sdb_decode_raw(ut8 *bout, const char *bin, int len);

// binfmt
int sdb_fmt_init (void *p, const char *fmt);
void sdb_fmt_free (void *p, const char *fmt);
int sdb_fmt_tobin(const char *_str, const char *fmt, void *stru);
char *sdb_fmt_tostr(void *stru, const char *fmt);

#ifdef __cplusplus
}
Expand Down
58 changes: 22 additions & 36 deletions shlr/sdb/src/util.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,62 +18,46 @@ SDB_API int sdb_check_value(const char *s) {
}

SDB_API int sdb_check_key(const char *s) {
const char *special_chars = "\"+-=[]:$;";
if (!s || !*s)
return 0;
for (; *s; s++) {
switch (*s) {
case '"':
case '+':
case '-':
case '=':
case '[':
case ']':
case ':':
case '$': // eval value of given key
case ';':
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<<5);
h ^= *s++;
}
while (*s)
h = (h+(h<<5))^*s++;
} else {
while (len--) {
h += (h<<5);
h ^= *s++;
}
while (len--)
h = (h+(h<<5))^*s++;
}
return h;
}

// assert (sizeof (s)>64)
SDB_API char *sdb_itoa(ut64 n, char *s, int base) {
static const char* lookup = "0123456789abcdef";
int i = 62;
if (!s) {
s = malloc (64);
if (!s) return NULL;
memset (s, 0, 64);
}
s[63] = '\0';
if (base==16) {
static const char* lookup = "0123456789abcdef";
do {
for (; n && i>0; n/=16)
s[i--] = lookup[(n % 16)];
if (i==0) break;
} while(n/=16);
s[i--] = 'x';
s[i--] = '0';
} else {
do {
for (; n && i>0; n/=10)
s[i--] = (n % 10) + '0';
if (i==0) break;
} while (n/=10);
}
return s+i+1;
}
Expand Down Expand Up @@ -102,19 +86,21 @@ SDB_API int sdb_alen(const char *str) {
}

SDB_API ut64 sdb_now () {
struct timeval now;
gettimeofday (&now, NULL);
return now.tv_sec;
struct timeval now;
if (!gettimeofday (&now, NULL))
return now.tv_sec;
return 0LL;
}

SDB_API ut64 sdb_unow () {
ut64 x;
struct timeval now;
gettimeofday (&now, NULL);
x = now.tv_sec;
x <<= 32;
x += now.tv_usec;
return x;
if (!gettimeofday (&now, NULL)) {
x = now.tv_sec;
x <<= 32;
x += now.tv_usec;
} else x = 0LL;
return x;
}

SDB_API int sdb_isnum (const char *s) {
Expand Down

0 comments on commit b48153d

Please sign in to comment.