From 0ed5e6d6531e98028159cce2b9deae7e40eafb9f Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Wed, 12 Nov 2014 12:55:51 +0100 Subject: [PATCH] Fix another memory leak. The array with type descriptors is populated with dynamically allocated strings, but they are never freed anywhere. To be able to free those strings easily, they are now initialized with NULL pointers instead of zero length strings. --- src/suunto_eonsteel_parser.c | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/src/suunto_eonsteel_parser.c b/src/suunto_eonsteel_parser.c index dbbcb43..aeb58c2 100644 --- a/src/suunto_eonsteel_parser.c +++ b/src/suunto_eonsteel_parser.c @@ -53,12 +53,22 @@ typedef struct suunto_eonsteel_parser_t { typedef int (*eon_data_cb_t)(unsigned short type, const struct type_desc *desc, const unsigned char *data, int len, void *user); +static void +desc_free (struct type_desc desc[], unsigned int count) +{ + for (unsigned int i = 0; i < count; ++i) { + free((void *)desc[i].desc); + free((void *)desc[i].format); + free((void *)desc[i].mod); + } +} + static int record_type(suunto_eonsteel_parser_t *eon, unsigned short type, const char *name, int namelen) { struct type_desc desc; const char *next; - desc.desc = desc.format = desc.mod = ""; + desc.desc = desc.format = desc.mod = NULL; do { int len; char *p; @@ -78,6 +88,7 @@ static int record_type(suunto_eonsteel_parser_t *eon, unsigned short type, const p = (char *) malloc(len-4); if (!p) { ERROR(eon->base.context, "out of memory"); + desc_free(&desc, 1); return -1; } memcpy(p, name+5, len-5); @@ -97,16 +108,23 @@ static int record_type(suunto_eonsteel_parser_t *eon, unsigned short type, const break; default: ERROR(eon->base.context, "Unknown type descriptor: %.*s", len, name); + desc_free(&desc, 1); + free(p); return -1; } } while ((name = next) != NULL); if (type > MAXTYPE) { ERROR(eon->base.context, "Type out of range (%04x: '%s' '%s' '%s')", - type, desc.desc, desc.format, desc.mod); + type, + desc.desc ? desc.desc : "", + desc.format ? desc.format : "", + desc.mod ? desc.mod : ""); + desc_free(&desc, 1); return -1; } + desc_free(eon->type_desc + type, 1); eon->type_desc[type] = desc; return 0; } @@ -449,6 +467,8 @@ static dc_status_t suunto_eonsteel_parser_set_data(dc_parser_t *parser, const unsigned char *data, unsigned int size) { suunto_eonsteel_parser_t *eon = (suunto_eonsteel_parser_t *) parser; + + desc_free(eon->type_desc, MAXTYPE); memset(eon->type_desc, 0, sizeof(eon->type_desc)); initialize_field_caches(eon); return DC_STATUS_SUCCESS; @@ -457,6 +477,9 @@ suunto_eonsteel_parser_set_data(dc_parser_t *parser, const unsigned char *data, static dc_status_t suunto_eonsteel_parser_destroy(dc_parser_t *parser) { + suunto_eonsteel_parser_t *eon = (suunto_eonsteel_parser_t *) parser; + + desc_free(eon->type_desc, MAXTYPE); free(parser); return DC_STATUS_SUCCESS; }