From 982b9e157a0db7ddf607ff2af94d0684ed43cc08 Mon Sep 17 00:00:00 2001 From: ethereal Date: Wed, 20 Jan 2016 12:09:32 -0800 Subject: [PATCH] Fixed several memory leaks. --- src/main.c | 8 ++++++++ src/yacjs.c | 41 +++++++++++++++++++++++++++-------------- src/yacjs_dict.c | 8 +++++--- 3 files changed, 40 insertions(+), 17 deletions(-) diff --git a/src/main.c b/src/main.c index 8c2e723..7376a1c 100644 --- a/src/main.c +++ b/src/main.c @@ -5,6 +5,9 @@ int main() { struct yacjs_node *root = yacjs_parse("{\"foo\": \"bar\", \"baz\": [\"a\", \"b\", \"c\"]}"); + yacjs_destroy(root); + root = NULL; + FILE *fp = fopen("test/test1.json", "r"); char buffer[32768]; int ret = fread(buffer, 1, 32768, fp); @@ -15,6 +18,9 @@ int main() { root = yacjs_parse(buffer); printf("root: %p\n", root); + printf("error: %i\n", yacjs_last_error()); + + /* struct yacjs_node *node = yacjs_node_array_elem(root, 0); node = yacjs_node_dict_get(node, "friends"); printf("%i friends\n", yacjs_node_array_size(node)); @@ -23,6 +29,8 @@ int main() { printf("second friend ID and name: %li, %s\n", yacjs_node_num(yacjs_node_dict_get(node, "id")), yacjs_node_str(yacjs_node_dict_get(node, "name"))); +*/ + yacjs_destroy(root); return 0; } diff --git a/src/yacjs.c b/src/yacjs.c index e33d09e..2952eab 100644 --- a/src/yacjs.c +++ b/src/yacjs.c @@ -8,10 +8,12 @@ #include "yacjs_dict.h" #include "yacjs_u8s.h" +#define zalloc(size) calloc(size, 1) + struct YACJS_NAME(node) { enum YACJS_NAME(node_type) type; union { - const char *string; + char *string; int64_t number; double fp; struct { @@ -82,13 +84,16 @@ void YACJS_NAME(destroy)(struct YACJS_NAME(node) *node) { static void destroy_helper(struct YACJS_NAME(node) *node) { if(node->type == YACJS_NAME_CAP(NODE_ARRAY)) { for(int i = 0; i < node->data.array.entries_count; i ++) { - YACJS_NAME(destroy)(node->data.array.entries + i); + destroy_helper(node->data.array.entries + i); } free(node->data.array.entries); } else if(node->type == YACJS_NAME_CAP(NODE_DICT)) { YACJS_NAME(dict_destroy)(node->data.dict, - (YACJS_NAME(dict_visitor))destroy_helper); + (YACJS_NAME(dict_visitor))YACJS_NAME(destroy)); + } + else if(node->type == YACJS_NAME_CAP(NODE_STRING)) { + free(node->data.string); } } @@ -273,19 +278,19 @@ static struct YACJS_NAME(node) *parse_any(const char **string) { if(type == TOKEN_OPENDICT) return parse_dict_contents(string); else if(type == TOKEN_OPENARRAY) return parse_array_contents(string); else if(type == TOKEN_STRING) { - struct YACJS_NAME(node) *build = malloc(sizeof(*build)); + struct YACJS_NAME(node) *build = zalloc(sizeof(*build)); build->type = YACJS_NAME_CAP(NODE_STRING); build->data.string = U8S_NAME(strndup)(s, len); return build; } else if(type == TOKEN_NUMBER) { - struct YACJS_NAME(node) *build = malloc(sizeof(*build)); + struct YACJS_NAME(node) *build = zalloc(sizeof(*build)); build->type = YACJS_NAME_CAP(NODE_NUMBER); build->data.number = strtoll(s, NULL, 0); return build; } else if(type == TOKEN_FLOAT) { - struct YACJS_NAME(node) *build = malloc(sizeof(*build)); + struct YACJS_NAME(node) *build = zalloc(sizeof(*build)); build->type = YACJS_NAME_CAP(NODE_FLOAT); char *e; build->data.fp = strtod(s, &e); @@ -297,13 +302,13 @@ static struct YACJS_NAME(node) *parse_any(const char **string) { return build; } else if(type == TOKEN_FALSE || type == TOKEN_TRUE) { - struct YACJS_NAME(node) *build = malloc(sizeof(*build)); + struct YACJS_NAME(node) *build = zalloc(sizeof(*build)); build->type = YACJS_NAME_CAP(NODE_BOOLEAN); build->data.boolean = type == TOKEN_TRUE; return build; } else if(type == TOKEN_NULL) { - struct YACJS_NAME(node) *build = malloc(sizeof(*build)); + struct YACJS_NAME(node) *build = zalloc(sizeof(*build)); build->type = YACJS_NAME_CAP(NODE_NULL); return build; } @@ -318,7 +323,7 @@ static struct YACJS_NAME(node) *parse_dict_contents(const char **string) { const char *s; int len; - struct YACJS_NAME(node) *result = malloc(sizeof(*result)); + struct YACJS_NAME(node) *result = zalloc(sizeof(*result)); result->type = YACJS_NAME_CAP(NODE_DICT); result->data.dict = YACJS_NAME(dict_make)(); @@ -327,6 +332,7 @@ static struct YACJS_NAME(node) *parse_dict_contents(const char **string) { if(type == TOKEN_CLOSEDICT) break; // we expect a string here if it's not a closing dictionary else if(type != TOKEN_STRING) { + YACJS_NAME(destroy)(result); return NULL; } @@ -335,13 +341,17 @@ static struct YACJS_NAME(node) *parse_dict_contents(const char **string) { // expect a colon after the name next_token(string, &len, &type); if(type != TOKEN_COLON) { + YACJS_NAME(destroy)(result); + free(ds); return NULL; } struct YACJS_NAME(node) *value = parse_any(string); if(value == NULL) { - // TODO: leaked memory + YACJS_NAME(destroy)(result); + YACJS_NAME(destroy)(value); + free(ds); return NULL; } @@ -356,7 +366,7 @@ static struct YACJS_NAME(node) *parse_dict_contents(const char **string) { } } if(!s) { - // TODO: leaked memory + YACJS_NAME(destroy)(result); return NULL; } @@ -368,7 +378,7 @@ static struct YACJS_NAME(node) *parse_array_contents(const char **string) { const char *s; int len; - struct YACJS_NAME(node) *result = malloc(sizeof(*result)); + struct YACJS_NAME(node) *result = zalloc(sizeof(*result)); result->type = YACJS_NAME_CAP(NODE_ARRAY); result->data.array.entries = NULL; result->data.array.entries_size = 0; @@ -383,7 +393,8 @@ static struct YACJS_NAME(node) *parse_array_contents(const char **string) { } struct YACJS_NAME(node) *next = parse_any(string); if(!next) { - // TODO: leaked memory + YACJS_NAME(destroy)(result); + YACJS_NAME(destroy)(next); return NULL; } @@ -395,6 +406,8 @@ static struct YACJS_NAME(node) *parse_array_contents(const char **string) { * (result->data.array.entries_size * 2 + 1)); if(nmem == NULL) { last_error = YACJS_NAME_CAP(ERROR_MEMORY); + YACJS_NAME(destroy)(result); + YACJS_NAME(destroy)(next); return NULL; } @@ -413,7 +426,7 @@ static struct YACJS_NAME(node) *parse_array_contents(const char **string) { } } if(!s) { - // TODO: leaked memory + YACJS_NAME(destroy)(result); return NULL; } diff --git a/src/yacjs_dict.c b/src/yacjs_dict.c index c59a40a..4222aa3 100644 --- a/src/yacjs_dict.c +++ b/src/yacjs_dict.c @@ -20,7 +20,7 @@ static char *ystrdup(const char *string); static uint64_t string_hash(const char *string); static void resize(struct YACJS_NAME(dict) *dict, int newsize); static void insert_helper(struct YACJS_NAME(dict) *dict, uint64_t hash, - const char *key, void *value); + char *key, void *value); struct YACJS_NAME(dict) *YACJS_NAME(dict_make)() { struct YACJS_NAME(dict) *result = malloc(sizeof(*result)); @@ -43,6 +43,7 @@ void YACJS_NAME(dict_destroy)(struct YACJS_NAME(dict) *dict, } } } + free(dict->entries); free(dict); } @@ -96,14 +97,15 @@ static void resize(struct YACJS_NAME(dict) *dict, int newsize) { insert_helper(dict, oentries[i].key_hash, oentries[i].key, oentries[i].value); } + free(oentries); } static void insert_helper(struct YACJS_NAME(dict) *dict, uint64_t hash, - const char *key, void *value) { + char *key, void *value) { for(int i = 0; i < dict->entries_size; i ++) { int in = (i+hash) % dict->entries_size; if(dict->entries[in].key) continue; - dict->entries[in].key = ystrdup(key); + dict->entries[in].key = key; dict->entries[in].key_hash = hash; dict->entries[in].value = value; break; -- 2.11.0