summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/xplist.c71
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;