diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/xplist.c | 71 |
1 files changed, 37 insertions, 34 deletions
diff --git a/src/xplist.c b/src/xplist.c index 19fbdbd..0e8b7e6 100644 --- a/src/xplist.c +++ b/src/xplist.c @@ -787,7 +787,9 @@ static char* text_parts_get_content(text_part_t *tp, int unesc_entities, size_t static void node_from_xml(parse_ctx ctx, plist_t *plist, uint32_t depth) { + char *tag = NULL; char *keyname = NULL; + plist_t subnode = NULL; const char *p = NULL; while (ctx->pos < ctx->end && !ctx->err) { parse_skip_ws(ctx); @@ -798,24 +800,27 @@ static void node_from_xml(parse_ctx ctx, plist_t *plist, uint32_t depth) p = ctx->pos; find_next(ctx, " \t\r\n", 4, 0); PLIST_XML_ERR("Expected: opening tag, found: %.*s\n", (int)(ctx->pos - p), p); - ctx->pos = ctx->end; ctx->err++; - break; + goto err_out; } ctx->pos++; if (ctx->pos >= ctx->end) { - break; + PLIST_XML_ERR("EOF while parsing tag\n"); + ctx->err++; + goto err_out; } if (*(ctx->pos) == '?') { find_str(ctx, "?>", 2, 1); - if (ctx->pos >= ctx->end) { - break; + if (ctx->pos >= ctx->end-2) { + PLIST_XML_ERR("EOF while looking for <? tag closing marker\n"); + ctx->err++; + goto err_out; } if (strncmp(ctx->pos, "?>", 2)) { PLIST_XML_ERR("Couldn't find <? tag closing marker\n"); - ctx->pos = ctx->end; - return; + ctx->err++; + goto err_out; } ctx->pos += 2; continue; @@ -826,8 +831,8 @@ static void node_from_xml(parse_ctx ctx, plist_t *plist, uint32_t depth) find_str(ctx,"-->", 3, 0); if (strncmp(ctx->pos, "-->", 3)) { PLIST_XML_ERR("Couldn't find end of comment\n"); - ctx->pos = ctx->end; - return; + ctx->err++; + goto err_out; } ctx->pos+=3; } else if (((ctx->end - ctx->pos) > 8) && !strncmp(ctx->pos, "!DOCTYPE", 8)) { @@ -850,16 +855,17 @@ static void node_from_xml(parse_ctx ctx, plist_t *plist, uint32_t depth) find_str(ctx, "]>", 2, 1); if (strncmp(ctx->pos, "]>", 2)) { PLIST_XML_ERR("Couldn't find end of DOCTYPE\n"); - ctx->pos = ctx->end; - return; + ctx->err++; + goto err_out; } ctx->pos += 2; } } else { p = ctx->pos; find_next(ctx, " \r\n\t>", 5, 1); - PLIST_XML_ERR("Invalid special tag <%.*s> encountered\n", (int)(ctx->pos - p), p); + PLIST_XML_ERR("Invalid or incomplete special tag <%.*s> encountered\n", (int)(ctx->pos - p), p); ctx->err++; + goto err_out; } continue; } else { @@ -869,13 +875,11 @@ static void node_from_xml(parse_ctx ctx, plist_t *plist, uint32_t depth) find_next(ctx," \r\n\t<>", 6, 0); if (ctx->pos >= ctx->end) { PLIST_XML_ERR("Unexpected EOF while parsing XML\n"); - ctx->pos = ctx->end; ctx->err++; - free(keyname); - return; + goto err_out; } int taglen = ctx->pos - p; - char *tag = malloc(taglen + 1); + tag = malloc(taglen + 1); strncpy(tag, p, taglen); tag[taglen] = '\0'; if (*ctx->pos != '>') { @@ -883,19 +887,13 @@ static void node_from_xml(parse_ctx ctx, plist_t *plist, uint32_t depth) } if (ctx->pos >= ctx->end) { PLIST_XML_ERR("Unexpected EOF while parsing XML\n"); - ctx->pos = ctx->end; ctx->err++; - free(tag); - free(keyname); - return; + goto err_out; } if (*ctx->pos != '>') { PLIST_XML_ERR("Missing '>' for tag <%s\n", tag); - ctx->pos = ctx->end; ctx->err++; - free(tag); - free(keyname); - return; + goto err_out; } if (*(ctx->pos-1) == '/') { int idx = ctx->pos - p - 1; @@ -906,9 +904,10 @@ static void node_from_xml(parse_ctx ctx, plist_t *plist, uint32_t depth) ctx->pos++; if (!strcmp(tag, "plist")) { free(tag); + tag = NULL; if (is_empty) { PLIST_XML_ERR("Empty plist tag\n"); - return; + break; } if (!*plist) { /* only process first plist node found */ @@ -919,19 +918,15 @@ static void node_from_xml(parse_ctx ctx, plist_t *plist, uint32_t depth) if (!*plist) { PLIST_XML_ERR("Empty plist tag\n"); } - free(tag); - free(keyname); - return; + goto err_out; } else if (depth == 1 && *plist) { PLIST_XML_ERR("Unexpected tag <%s> found while </plist> is expected\n", tag); ctx->err++; - free(tag); - free(keyname); - return; + goto err_out; } plist_data_t data = plist_new_plist_data(); - plist_t subnode = plist_new_node(data); + subnode = plist_new_node(data); if (!strcmp(tag, XPLIST_DICT)) { data->type = PLIST_DICT; @@ -1052,6 +1047,7 @@ static void node_from_xml(parse_ctx ctx, plist_t *plist, uint32_t depth) if (!strcmp(tag, "key") && !keyname && *plist && (plist_get_node_type(*plist) == PLIST_DICT)) { keyname = str; free(tag); + tag = NULL; plist_free(subnode); subnode = NULL; continue; @@ -1220,21 +1216,28 @@ static void node_from_xml(parse_ctx ctx, plist_t *plist, uint32_t depth) break; } } -err_out: free(tag); + tag = NULL; free(keyname); keyname = NULL; plist_free(subnode); subnode = NULL; - if (closing_tag || ctx->err) { + if (closing_tag) { break; } } } + if (depth == 1) { PLIST_XML_ERR("EOF while </plist> tag is expected\n"); ctx->err++; } + +err_out: + free(tag); + free(keyname); + plist_free(subnode); + if (ctx->err) { plist_free(*plist); *plist = NULL; |