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 | |||
| 787 | 787 | ||
| 788 | static void node_from_xml(parse_ctx ctx, plist_t *plist, uint32_t depth) | 788 | static void node_from_xml(parse_ctx ctx, plist_t *plist, uint32_t depth) |
| 789 | { | 789 | { |
| 790 | char *tag = NULL; | ||
| 790 | char *keyname = NULL; | 791 | char *keyname = NULL; |
| 792 | plist_t subnode = NULL; | ||
| 791 | const char *p = NULL; | 793 | const char *p = NULL; |
| 792 | while (ctx->pos < ctx->end && !ctx->err) { | 794 | while (ctx->pos < ctx->end && !ctx->err) { |
| 793 | parse_skip_ws(ctx); | 795 | parse_skip_ws(ctx); |
| @@ -798,24 +800,27 @@ static void node_from_xml(parse_ctx ctx, plist_t *plist, uint32_t depth) | |||
| 798 | p = ctx->pos; | 800 | p = ctx->pos; |
| 799 | find_next(ctx, " \t\r\n", 4, 0); | 801 | find_next(ctx, " \t\r\n", 4, 0); |
| 800 | PLIST_XML_ERR("Expected: opening tag, found: %.*s\n", (int)(ctx->pos - p), p); | 802 | PLIST_XML_ERR("Expected: opening tag, found: %.*s\n", (int)(ctx->pos - p), p); |
| 801 | ctx->pos = ctx->end; | ||
| 802 | ctx->err++; | 803 | ctx->err++; |
| 803 | break; | 804 | goto err_out; |
| 804 | } | 805 | } |
| 805 | ctx->pos++; | 806 | ctx->pos++; |
| 806 | if (ctx->pos >= ctx->end) { | 807 | if (ctx->pos >= ctx->end) { |
| 807 | break; | 808 | PLIST_XML_ERR("EOF while parsing tag\n"); |
| 809 | ctx->err++; | ||
| 810 | goto err_out; | ||
| 808 | } | 811 | } |
| 809 | 812 | ||
| 810 | if (*(ctx->pos) == '?') { | 813 | if (*(ctx->pos) == '?') { |
| 811 | find_str(ctx, "?>", 2, 1); | 814 | find_str(ctx, "?>", 2, 1); |
| 812 | if (ctx->pos >= ctx->end) { | 815 | if (ctx->pos >= ctx->end-2) { |
| 813 | break; | 816 | PLIST_XML_ERR("EOF while looking for <? tag closing marker\n"); |
| 817 | ctx->err++; | ||
| 818 | goto err_out; | ||
| 814 | } | 819 | } |
| 815 | if (strncmp(ctx->pos, "?>", 2)) { | 820 | if (strncmp(ctx->pos, "?>", 2)) { |
| 816 | PLIST_XML_ERR("Couldn't find <? tag closing marker\n"); | 821 | PLIST_XML_ERR("Couldn't find <? tag closing marker\n"); |
| 817 | ctx->pos = ctx->end; | 822 | ctx->err++; |
| 818 | return; | 823 | goto err_out; |
| 819 | } | 824 | } |
| 820 | ctx->pos += 2; | 825 | ctx->pos += 2; |
| 821 | continue; | 826 | continue; |
| @@ -826,8 +831,8 @@ static void node_from_xml(parse_ctx ctx, plist_t *plist, uint32_t depth) | |||
| 826 | find_str(ctx,"-->", 3, 0); | 831 | find_str(ctx,"-->", 3, 0); |
| 827 | if (strncmp(ctx->pos, "-->", 3)) { | 832 | if (strncmp(ctx->pos, "-->", 3)) { |
| 828 | PLIST_XML_ERR("Couldn't find end of comment\n"); | 833 | PLIST_XML_ERR("Couldn't find end of comment\n"); |
| 829 | ctx->pos = ctx->end; | 834 | ctx->err++; |
| 830 | return; | 835 | goto err_out; |
| 831 | } | 836 | } |
| 832 | ctx->pos+=3; | 837 | ctx->pos+=3; |
| 833 | } else if (((ctx->end - ctx->pos) > 8) && !strncmp(ctx->pos, "!DOCTYPE", 8)) { | 838 | } 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) | |||
| 850 | find_str(ctx, "]>", 2, 1); | 855 | find_str(ctx, "]>", 2, 1); |
| 851 | if (strncmp(ctx->pos, "]>", 2)) { | 856 | if (strncmp(ctx->pos, "]>", 2)) { |
| 852 | PLIST_XML_ERR("Couldn't find end of DOCTYPE\n"); | 857 | PLIST_XML_ERR("Couldn't find end of DOCTYPE\n"); |
| 853 | ctx->pos = ctx->end; | 858 | ctx->err++; |
| 854 | return; | 859 | goto err_out; |
| 855 | } | 860 | } |
| 856 | ctx->pos += 2; | 861 | ctx->pos += 2; |
| 857 | } | 862 | } |
| 858 | } else { | 863 | } else { |
| 859 | p = ctx->pos; | 864 | p = ctx->pos; |
| 860 | find_next(ctx, " \r\n\t>", 5, 1); | 865 | find_next(ctx, " \r\n\t>", 5, 1); |
| 861 | PLIST_XML_ERR("Invalid special tag <%.*s> encountered\n", (int)(ctx->pos - p), p); | 866 | PLIST_XML_ERR("Invalid or incomplete special tag <%.*s> encountered\n", (int)(ctx->pos - p), p); |
| 862 | ctx->err++; | 867 | ctx->err++; |
| 868 | goto err_out; | ||
| 863 | } | 869 | } |
| 864 | continue; | 870 | continue; |
| 865 | } else { | 871 | } else { |
| @@ -869,13 +875,11 @@ static void node_from_xml(parse_ctx ctx, plist_t *plist, uint32_t depth) | |||
| 869 | find_next(ctx," \r\n\t<>", 6, 0); | 875 | find_next(ctx," \r\n\t<>", 6, 0); |
| 870 | if (ctx->pos >= ctx->end) { | 876 | if (ctx->pos >= ctx->end) { |
| 871 | PLIST_XML_ERR("Unexpected EOF while parsing XML\n"); | 877 | PLIST_XML_ERR("Unexpected EOF while parsing XML\n"); |
| 872 | ctx->pos = ctx->end; | ||
| 873 | ctx->err++; | 878 | ctx->err++; |
| 874 | free(keyname); | 879 | goto err_out; |
| 875 | return; | ||
| 876 | } | 880 | } |
| 877 | int taglen = ctx->pos - p; | 881 | int taglen = ctx->pos - p; |
| 878 | char *tag = malloc(taglen + 1); | 882 | tag = malloc(taglen + 1); |
| 879 | strncpy(tag, p, taglen); | 883 | strncpy(tag, p, taglen); |
| 880 | tag[taglen] = '\0'; | 884 | tag[taglen] = '\0'; |
| 881 | if (*ctx->pos != '>') { | 885 | if (*ctx->pos != '>') { |
| @@ -883,19 +887,13 @@ static void node_from_xml(parse_ctx ctx, plist_t *plist, uint32_t depth) | |||
| 883 | } | 887 | } |
| 884 | if (ctx->pos >= ctx->end) { | 888 | if (ctx->pos >= ctx->end) { |
| 885 | PLIST_XML_ERR("Unexpected EOF while parsing XML\n"); | 889 | PLIST_XML_ERR("Unexpected EOF while parsing XML\n"); |
| 886 | ctx->pos = ctx->end; | ||
| 887 | ctx->err++; | 890 | ctx->err++; |
| 888 | free(tag); | 891 | goto err_out; |
| 889 | free(keyname); | ||
| 890 | return; | ||
| 891 | } | 892 | } |
| 892 | if (*ctx->pos != '>') { | 893 | if (*ctx->pos != '>') { |
| 893 | PLIST_XML_ERR("Missing '>' for tag <%s\n", tag); | 894 | PLIST_XML_ERR("Missing '>' for tag <%s\n", tag); |
| 894 | ctx->pos = ctx->end; | ||
| 895 | ctx->err++; | 895 | ctx->err++; |
| 896 | free(tag); | 896 | goto err_out; |
| 897 | free(keyname); | ||
| 898 | return; | ||
| 899 | } | 897 | } |
| 900 | if (*(ctx->pos-1) == '/') { | 898 | if (*(ctx->pos-1) == '/') { |
| 901 | int idx = ctx->pos - p - 1; | 899 | int idx = ctx->pos - p - 1; |
| @@ -906,9 +904,10 @@ static void node_from_xml(parse_ctx ctx, plist_t *plist, uint32_t depth) | |||
| 906 | ctx->pos++; | 904 | ctx->pos++; |
| 907 | if (!strcmp(tag, "plist")) { | 905 | if (!strcmp(tag, "plist")) { |
| 908 | free(tag); | 906 | free(tag); |
| 907 | tag = NULL; | ||
| 909 | if (is_empty) { | 908 | if (is_empty) { |
| 910 | PLIST_XML_ERR("Empty plist tag\n"); | 909 | PLIST_XML_ERR("Empty plist tag\n"); |
| 911 | return; | 910 | break; |
| 912 | } | 911 | } |
| 913 | if (!*plist) { | 912 | if (!*plist) { |
| 914 | /* only process first plist node found */ | 913 | /* only process first plist node found */ |
| @@ -919,19 +918,15 @@ static void node_from_xml(parse_ctx ctx, plist_t *plist, uint32_t depth) | |||
| 919 | if (!*plist) { | 918 | if (!*plist) { |
| 920 | PLIST_XML_ERR("Empty plist tag\n"); | 919 | PLIST_XML_ERR("Empty plist tag\n"); |
| 921 | } | 920 | } |
| 922 | free(tag); | 921 | goto err_out; |
| 923 | free(keyname); | ||
| 924 | return; | ||
| 925 | } else if (depth == 1 && *plist) { | 922 | } else if (depth == 1 && *plist) { |
| 926 | PLIST_XML_ERR("Unexpected tag <%s> found while </plist> is expected\n", tag); | 923 | PLIST_XML_ERR("Unexpected tag <%s> found while </plist> is expected\n", tag); |
| 927 | ctx->err++; | 924 | ctx->err++; |
| 928 | free(tag); | 925 | goto err_out; |
| 929 | free(keyname); | ||
| 930 | return; | ||
| 931 | } | 926 | } |
| 932 | 927 | ||
| 933 | plist_data_t data = plist_new_plist_data(); | 928 | plist_data_t data = plist_new_plist_data(); |
| 934 | plist_t subnode = plist_new_node(data); | 929 | subnode = plist_new_node(data); |
| 935 | 930 | ||
| 936 | if (!strcmp(tag, XPLIST_DICT)) { | 931 | if (!strcmp(tag, XPLIST_DICT)) { |
| 937 | data->type = PLIST_DICT; | 932 | data->type = PLIST_DICT; |
| @@ -1052,6 +1047,7 @@ static void node_from_xml(parse_ctx ctx, plist_t *plist, uint32_t depth) | |||
| 1052 | if (!strcmp(tag, "key") && !keyname && *plist && (plist_get_node_type(*plist) == PLIST_DICT)) { | 1047 | if (!strcmp(tag, "key") && !keyname && *plist && (plist_get_node_type(*plist) == PLIST_DICT)) { |
| 1053 | keyname = str; | 1048 | keyname = str; |
| 1054 | free(tag); | 1049 | free(tag); |
| 1050 | tag = NULL; | ||
| 1055 | plist_free(subnode); | 1051 | plist_free(subnode); |
| 1056 | subnode = NULL; | 1052 | subnode = NULL; |
| 1057 | continue; | 1053 | continue; |
| @@ -1220,21 +1216,28 @@ static void node_from_xml(parse_ctx ctx, plist_t *plist, uint32_t depth) | |||
| 1220 | break; | 1216 | break; |
| 1221 | } | 1217 | } |
| 1222 | } | 1218 | } |
| 1223 | err_out: | ||
| 1224 | free(tag); | 1219 | free(tag); |
| 1220 | tag = NULL; | ||
| 1225 | free(keyname); | 1221 | free(keyname); |
| 1226 | keyname = NULL; | 1222 | keyname = NULL; |
| 1227 | plist_free(subnode); | 1223 | plist_free(subnode); |
| 1228 | subnode = NULL; | 1224 | subnode = NULL; |
| 1229 | if (closing_tag || ctx->err) { | 1225 | if (closing_tag) { |
| 1230 | break; | 1226 | break; |
| 1231 | } | 1227 | } |
| 1232 | } | 1228 | } |
| 1233 | } | 1229 | } |
| 1230 | |||
| 1234 | if (depth == 1) { | 1231 | if (depth == 1) { |
| 1235 | PLIST_XML_ERR("EOF while </plist> tag is expected\n"); | 1232 | PLIST_XML_ERR("EOF while </plist> tag is expected\n"); |
| 1236 | ctx->err++; | 1233 | ctx->err++; |
| 1237 | } | 1234 | } |
| 1235 | |||
| 1236 | err_out: | ||
| 1237 | free(tag); | ||
| 1238 | free(keyname); | ||
| 1239 | plist_free(subnode); | ||
| 1240 | |||
| 1238 | if (ctx->err) { | 1241 | if (ctx->err) { |
| 1239 | plist_free(*plist); | 1242 | plist_free(*plist); |
| 1240 | *plist = NULL; | 1243 | *plist = NULL; |
