diff options
author | Nikias Bassen | 2017-02-06 20:02:39 +0100 |
---|---|---|
committer | Nikias Bassen | 2017-02-06 20:02:39 +0100 |
commit | 35fdf8e73b9ee75b880cb9ff2de5491d7ddae20b (patch) | |
tree | 3209a50fdf1b2a53ffd4c0d93ebf81018dfaee2b | |
parent | c98451f9eabb68df3dfabaedc9e5fee81fec2fd7 (diff) | |
download | libplist-35fdf8e73b9ee75b880cb9ff2de5491d7ddae20b.tar.gz libplist-35fdf8e73b9ee75b880cb9ff2de5491d7ddae20b.tar.bz2 |
xplist: Prevent memory leaks when parsing fails
-rw-r--r-- | src/xplist.c | 57 |
1 files changed, 20 insertions, 37 deletions
diff --git a/src/xplist.c b/src/xplist.c index 98d7375..19fbdbd 100644 --- a/src/xplist.c +++ b/src/xplist.c @@ -944,9 +944,8 @@ static void node_from_xml(parse_ctx ctx, plist_t *plist, uint32_t depth) if (!tp) { PLIST_XML_ERR("Could not parse text content for '%s' node\n", tag); text_parts_free(first_part.next); - free(tag); - free(keyname); - break; + ctx->err++; + goto err_out; } if (tp->begin) { int requires_free = 0; @@ -955,9 +954,7 @@ static void node_from_xml(parse_ctx ctx, plist_t *plist, uint32_t depth) PLIST_XML_ERR("Could not get text content for '%s' node\n", tag); text_parts_free(first_part.next); ctx->err++; - free(tag); - free(keyname); - break; + goto err_out; } char *str = str_content; int is_negative = 0; @@ -998,9 +995,8 @@ static void node_from_xml(parse_ctx ctx, plist_t *plist, uint32_t depth) if (!tp) { PLIST_XML_ERR("Could not parse text content for '%s' node\n", tag); text_parts_free(first_part.next); - free(tag); - free(keyname); - break; + ctx->err++; + goto err_out; } if (tp->begin) { int requires_free = 0; @@ -1009,9 +1005,7 @@ static void node_from_xml(parse_ctx ctx, plist_t *plist, uint32_t depth) PLIST_XML_ERR("Could not get text content for '%s' node\n", tag); text_parts_free(first_part.next); ctx->err++; - free(tag); - free(keyname); - break; + goto err_out; } data->realval = atof(str_content); if (requires_free) { @@ -1045,18 +1039,15 @@ static void node_from_xml(parse_ctx ctx, plist_t *plist, uint32_t depth) if (!tp) { PLIST_XML_ERR("Could not parse text content for '%s' node\n", tag); text_parts_free(first_part.next); - free(tag); - free(keyname); - break; + ctx->err++; + goto err_out; } str = text_parts_get_content(tp, 1, &length, NULL); text_parts_free(first_part.next); if (!str) { PLIST_XML_ERR("Could not get text content for '%s' node\n", tag); ctx->err++; - free(tag); - free(keyname); - return; + goto err_out; } if (!strcmp(tag, "key") && !keyname && *plist && (plist_get_node_type(*plist) == PLIST_DICT)) { keyname = str; @@ -1080,9 +1071,8 @@ static void node_from_xml(parse_ctx ctx, plist_t *plist, uint32_t depth) if (!tp) { PLIST_XML_ERR("Could not parse text content for '%s' node\n", tag); text_parts_free(first_part.next); - free(tag); - free(keyname); - break; + ctx->err++; + goto err_out; } if (tp->begin) { int requires_free = 0; @@ -1091,9 +1081,7 @@ static void node_from_xml(parse_ctx ctx, plist_t *plist, uint32_t depth) PLIST_XML_ERR("Could not get text content for '%s' node\n", tag); text_parts_free(first_part.next); ctx->err++; - free(tag); - free(keyname); - break; + goto err_out; } size_t size = tp->length; data->buff = base64decode(str_content, &size); @@ -1113,9 +1101,8 @@ static void node_from_xml(parse_ctx ctx, plist_t *plist, uint32_t depth) if (!tp) { PLIST_XML_ERR("Could not parse text content for '%s' node\n", tag); text_parts_free(first_part.next); - free(tag); - free(keyname); - break; + ctx->err++; + goto err_out; } Time64_T timev = 0; if (tp->begin) { @@ -1126,9 +1113,7 @@ static void node_from_xml(parse_ctx ctx, plist_t *plist, uint32_t depth) PLIST_XML_ERR("Could not get text content for '%s' node\n", tag); text_parts_free(first_part.next); ctx->err++; - free(tag); - free(keyname); - break; + goto err_out; } if ((length >= 11) && (length < 32)) { @@ -1157,9 +1142,7 @@ static void node_from_xml(parse_ctx ctx, plist_t *plist, uint32_t depth) PLIST_XML_ERR("Unexpected tag <%s%s> encountered\n", tag, (is_empty) ? "/" : ""); ctx->pos = ctx->end; ctx->err++; - free(tag); - free(keyname); - return; + goto err_out; } if (subnode && !closing_tag) { /* parse sub nodes for structured types */ @@ -1169,9 +1152,7 @@ static void node_from_xml(parse_ctx ctx, plist_t *plist, uint32_t depth) node_from_xml(ctx, &subnode, depth+1); if (ctx->err) { /* make sure to bail out if parsing failed */ - free(tag); - free(keyname); - return; + goto err_out; } if ((data->type == PLIST_DICT) && (plist_dict_get_size(subnode) == 1)) { /* convert XML CF$UID dictionaries to PLIST_UID nodes */ @@ -1239,11 +1220,13 @@ static void node_from_xml(parse_ctx ctx, plist_t *plist, uint32_t depth) break; } } +err_out: free(tag); free(keyname); keyname = NULL; plist_free(subnode); - if (closing_tag) { + subnode = NULL; + if (closing_tag || ctx->err) { break; } } |