diff --git a/daemon/redis.c b/daemon/redis.c index 1428aca33..747e30317 100644 --- a/daemon/redis.c +++ b/daemon/redis.c @@ -691,13 +691,12 @@ INLINE void json_builder_add_string_value_uri_enc(JsonBuilder *builder, const ch str_uri_encode_len(enc, tmp, len); json_builder_add_string_value(builder,enc); } -INLINE char* json_reader_get_string_value_uri_enc(JsonReader *root_reader, int *lenp) { - const char *str = json_reader_get_string_value(root_reader); - char *ret; - int len = str_uri_decode_len(&ret, str, strlen(str)); - if (lenp) - *lenp = len; - return ret; // must be free'd +INLINE str *json_reader_get_string_value_uri_enc(JsonReader *root_reader) { + const char *s = json_reader_get_string_value(root_reader); + if (!s) + return NULL; + str *out = str_uri_decode_len(s, strlen(s)); + return out; // must be free'd } static int json_get_hash(struct redis_hash *out, struct call* c, @@ -706,7 +705,6 @@ static int json_get_hash(struct redis_hash *out, struct call* c, static unsigned int MAXKEYLENGTH = 512; char key_concatted[MAXKEYLENGTH]; int rc=0; - str tmpstr; if (!c) goto err; @@ -737,10 +735,10 @@ static int json_get_hash(struct redis_hash *out, struct call* c, rlog(LOG_ERROR, "Could not read json member: %s",*members); goto err3; } - str_init(&tmpstr,(char*)json_reader_get_string_value_uri_enc(c->root_reader,&tmpstr.len)); + str *val = json_reader_get_string_value_uri_enc(c->root_reader); char* tmp = strdup(*members); - if (g_hash_table_insert_check(out->ht, tmp, str_dup(&tmpstr)) != TRUE) { + if (g_hash_table_insert_check(out->ht, tmp, val) != TRUE) { ilog(LOG_WARNING,"Key %s already exists", tmp); goto err3; } @@ -880,7 +878,6 @@ static int json_build_list_cb(GQueue *q, struct call *c, const char *key, unsigned int idx, struct redis_list *list, int (*cb)(str *, GQueue *, struct redis_list *, void *), void *ptr) { - str s; char key_concatted[256]; snprintf(key_concatted, 256, "%s-%u", key, idx); @@ -890,14 +887,14 @@ static int json_build_list_cb(GQueue *q, struct call *c, const char *key, for (int jidx=0; jidx < json_reader_count_elements(c->root_reader); ++jidx) { if (!json_reader_read_element(c->root_reader,jidx)) rlog(LOG_ERROR,"Element in array not found."); - char *strp = s.s = json_reader_get_string_value_uri_enc(c->root_reader, &s.len); - if (!strp) + str *s = json_reader_get_string_value_uri_enc(c->root_reader); + if (!s) rlog(LOG_ERROR,"String in json not found."); - if (cb(&s, q, list, ptr)) { - free(s.s); + if (cb(s, q, list, ptr)) { + free(s); return -1; } - free(strp); + free(s); json_reader_end_element(c->root_reader); } json_reader_end_member (c->root_reader); diff --git a/daemon/str.c b/daemon/str.c index 21d99e81f..631e039c1 100644 --- a/daemon/str.c +++ b/daemon/str.c @@ -71,10 +71,10 @@ int str_uri_encode_len(char *out, const char *in, int len) { return out - ori_out; } -int str_uri_decode_len(char **out, const char *in, int in_len) { +str *str_uri_decode_len(const char *in, int in_len) { const char *end = in + in_len; - *out = malloc(in_len + 1); - char *outp = *out; + str *ret = str_alloc(in_len); + char *outp = ret->s; while (in < end) { if (*in != '%') { @@ -83,9 +83,8 @@ int str_uri_decode_len(char **out, const char *in, int in_len) { } if (end - in < 3 || !g_ascii_isxdigit(in[1]) || !g_ascii_isxdigit(in[2])) { - free(*out); - *out = NULL; - return -1; + free(ret); + return NULL; } unsigned char c = g_ascii_xdigit_value(in[1]) << 4 | g_ascii_xdigit_value(in[2]); @@ -94,5 +93,6 @@ int str_uri_decode_len(char **out, const char *in, int in_len) { } *outp = 0; - return outp - *out; + ret->len = outp - ret->s; + return ret; } diff --git a/lib/str.h b/lib/str.h index 6eaba3a73..4880ff6c1 100644 --- a/lib/str.h +++ b/lib/str.h @@ -50,6 +50,8 @@ INLINE str *str_init(str *out, char *s); INLINE str *str_init_len(str *out, char *s, int len); INLINE str *str_init_len_assert_len(str *out, char *s, int buflen, int len); #define str_init_len_assert(out, s, len) str_init_len_assert_len(out, s, sizeof(s), len) +/* returns new str object with uninitialized buffer large enough to hold `len` characters (+1 for null byte) */ +INLINE str *str_alloc(int len); /* returns new str object allocated with malloc, including buffer */ INLINE str *str_dup(const str *s); /* returns new str object allocated from chunk, including buffer */ @@ -90,8 +92,8 @@ void str_slice_free(void *); /* saves "in" into "out" pseudo-URI encoded. "out" point to a buffer with sufficient length. returns length */ int str_uri_encode_len(char *out, const char *in, int in_len); INLINE int str_uri_encode(char *out, const str *in); -/* reverse of the above. stores newly allocated buffer in *out. returns length */ -int str_uri_decode_len(char **out, const char *in, int in_len); +/* reverse of the above. returns newly allocated str + buffer as per str_alloc (must be free'd) */ +str *str_uri_decode_len(const char *in, int in_len); @@ -187,10 +189,16 @@ INLINE str *str_init_len_assert_len(str *out, char *s, int buflen, int len) { assert(buflen >= len); return str_init_len(out, s, len); } -INLINE str *str_dup(const str *s) { +INLINE str *str_alloc(int len) { str *r; - r = malloc(sizeof(*r) + s->len + 1); + r = malloc(sizeof(*r) + len + 1); r->s = ((char *) r) + sizeof(*r); + r->len = 0; + return r; +} +INLINE str *str_dup(const str *s) { + str *r; + r = str_alloc(s->len); r->len = s->len; memcpy(r->s, s->s, s->len); r->s[s->len] = '\0';