diff options
Diffstat (limited to 'src/xplist.c')
| -rw-r--r-- | src/xplist.c | 32 |
1 files changed, 17 insertions, 15 deletions
diff --git a/src/xplist.c b/src/xplist.c index a445dc5..de5227a 100644 --- a/src/xplist.c +++ b/src/xplist.c | |||
| @@ -1170,8 +1170,9 @@ static plist_err_t node_from_xml(parse_ctx ctx, plist_t *plist) | |||
| 1170 | ctx->pos++; | 1170 | ctx->pos++; |
| 1171 | if (!strcmp(tag, "plist")) { | 1171 | if (!strcmp(tag, "plist")) { |
| 1172 | if (!node_path && *plist) { | 1172 | if (!node_path && *plist) { |
| 1173 | /* we don't allow another top-level <plist> */ | 1173 | PLIST_XML_ERR("Multiple top-level <plist> elements encountered\n"); |
| 1174 | break; | 1174 | ctx->err = PLIST_ERR_PARSE; |
| 1175 | goto err_out; | ||
| 1175 | } | 1176 | } |
| 1176 | if (is_empty) { | 1177 | if (is_empty) { |
| 1177 | PLIST_XML_ERR("Empty plist tag\n"); | 1178 | PLIST_XML_ERR("Empty plist tag\n"); |
| @@ -1403,12 +1404,6 @@ static plist_err_t node_from_xml(parse_ctx ctx, plist_t *plist) | |||
| 1403 | data->length = length; | 1404 | data->length = length; |
| 1404 | } | 1405 | } |
| 1405 | } else { | 1406 | } else { |
| 1406 | if (!strcmp(tag, "key") && !keyname && parent && (plist_get_node_type(parent) == PLIST_DICT)) { | ||
| 1407 | keyname = strdup(""); | ||
| 1408 | plist_free(subnode); | ||
| 1409 | subnode = NULL; | ||
| 1410 | continue; | ||
| 1411 | } | ||
| 1412 | data->strval = strdup(""); | 1407 | data->strval = strdup(""); |
| 1413 | data->length = 0; | 1408 | data->length = 0; |
| 1414 | } | 1409 | } |
| @@ -1501,14 +1496,15 @@ static plist_err_t node_from_xml(parse_ctx ctx, plist_t *plist) | |||
| 1501 | } | 1496 | } |
| 1502 | if (subnode && !closing_tag) { | 1497 | if (subnode && !closing_tag) { |
| 1503 | if (!*plist) { | 1498 | if (!*plist) { |
| 1504 | /* first node, make this node the parent node */ | 1499 | /* first value node inside <plist> */ |
| 1505 | *plist = subnode; | 1500 | *plist = subnode; |
| 1506 | if (data->type != PLIST_DICT && data->type != PLIST_ARRAY) { | 1501 | |
| 1507 | /* if the first node is not a structered node, we're done */ | 1502 | if (data->type == PLIST_DICT || data->type == PLIST_ARRAY) { |
| 1508 | subnode = NULL; | 1503 | parent = subnode; |
| 1509 | goto err_out; | 1504 | } else { |
| 1505 | /* scalar root: keep parsing until </plist> */ | ||
| 1506 | parent = NULL; | ||
| 1510 | } | 1507 | } |
| 1511 | parent = subnode; | ||
| 1512 | } else if (parent) { | 1508 | } else if (parent) { |
| 1513 | switch (plist_get_node_type(parent)) { | 1509 | switch (plist_get_node_type(parent)) { |
| 1514 | case PLIST_DICT: | 1510 | case PLIST_DICT: |
| @@ -1528,6 +1524,11 @@ static plist_err_t node_from_xml(parse_ctx ctx, plist_t *plist) | |||
| 1528 | ctx->err = PLIST_ERR_PARSE; | 1524 | ctx->err = PLIST_ERR_PARSE; |
| 1529 | goto err_out; | 1525 | goto err_out; |
| 1530 | } | 1526 | } |
| 1527 | } else { | ||
| 1528 | /* We already produced root, and we're not inside a container */ | ||
| 1529 | PLIST_XML_ERR("Unexpected tag <%s> found while </plist> is expected\n", tag); | ||
| 1530 | ctx->err = PLIST_ERR_PARSE; | ||
| 1531 | goto err_out; | ||
| 1531 | } | 1532 | } |
| 1532 | if (!is_empty && (data->type == PLIST_DICT || data->type == PLIST_ARRAY)) { | 1533 | if (!is_empty && (data->type == PLIST_DICT || data->type == PLIST_ARRAY)) { |
| 1533 | if (depth >= PLIST_MAX_NESTING_DEPTH) { | 1534 | if (depth >= PLIST_MAX_NESTING_DEPTH) { |
| @@ -1547,6 +1548,8 @@ static plist_err_t node_from_xml(parse_ctx ctx, plist_t *plist) | |||
| 1547 | 1548 | ||
| 1548 | depth++; | 1549 | depth++; |
| 1549 | parent = subnode; | 1550 | parent = subnode; |
| 1551 | } else { | ||
| 1552 | /* If we inserted a child scalar into a container, nothing to push. */ | ||
| 1550 | } | 1553 | } |
| 1551 | subnode = NULL; | 1554 | subnode = NULL; |
| 1552 | } | 1555 | } |
| @@ -1587,7 +1590,6 @@ handle_closing: | |||
| 1587 | node_path = (struct node_path_item*)node_path->prev; | 1590 | node_path = (struct node_path_item*)node_path->prev; |
| 1588 | free(path_item); | 1591 | free(path_item); |
| 1589 | parent = (parent) ? ((node_t)parent)->parent : NULL; | 1592 | parent = (parent) ? ((node_t)parent)->parent : NULL; |
| 1590 | /* parent can be NULL when we just closed the root node; keep parsing */ | ||
| 1591 | } | 1593 | } |
| 1592 | free(keyname); | 1594 | free(keyname); |
| 1593 | keyname = NULL; | 1595 | keyname = NULL; |
