diff options
| author | 2016-12-21 03:46:02 +0100 | |
|---|---|---|
| committer | 2016-12-21 03:46:02 +0100 | |
| commit | d98ef4146e4e796e267284f37e06c86e75fcf30f (patch) | |
| tree | 3d109c97e570a3e801a30bee980321348fb5b596 /src/xplist.c | |
| parent | 793228208a6523bdbe434ed536c5669e4bb04f7c (diff) | |
| download | libplist-d98ef4146e4e796e267284f37e06c86e75fcf30f.tar.gz libplist-d98ef4146e4e796e267284f37e06c86e75fcf30f.tar.bz2 | |
xplist: Make sure to correctly parse for closing tags of structured nodes
Diffstat (limited to 'src/xplist.c')
| -rw-r--r-- | src/xplist.c | 52 |
1 files changed, 45 insertions, 7 deletions
diff --git a/src/xplist.c b/src/xplist.c index 250b623..ec75226 100644 --- a/src/xplist.c +++ b/src/xplist.c | |||
| @@ -762,7 +762,7 @@ static char* text_parts_get_content(text_part_t *tp, int unesc_entities, size_t | |||
| 762 | return str; | 762 | return str; |
| 763 | } | 763 | } |
| 764 | 764 | ||
| 765 | static void node_from_xml(parse_ctx ctx, plist_t *plist) | 765 | static void node_from_xml(parse_ctx ctx, plist_t *plist, uint32_t depth) |
| 766 | { | 766 | { |
| 767 | char *keyname = NULL; | 767 | char *keyname = NULL; |
| 768 | while (ctx->pos < ctx->end && !ctx->err) { | 768 | while (ctx->pos < ctx->end && !ctx->err) { |
| @@ -886,9 +886,22 @@ static void node_from_xml(parse_ctx ctx, plist_t *plist) | |||
| 886 | } | 886 | } |
| 887 | if (!*plist) { | 887 | if (!*plist) { |
| 888 | /* only process first plist node found */ | 888 | /* only process first plist node found */ |
| 889 | node_from_xml(ctx, plist); | 889 | node_from_xml(ctx, plist, depth+1); |
| 890 | } | 890 | } |
| 891 | continue; | 891 | continue; |
| 892 | } else if (depth == 1 && !strcmp(tag, "/plist")) { | ||
| 893 | if (!*plist) { | ||
| 894 | PLIST_XML_ERR("Empty plist tag\n"); | ||
| 895 | } | ||
| 896 | free(tag); | ||
| 897 | free(keyname); | ||
| 898 | return; | ||
| 899 | } else if (depth == 1 && *plist) { | ||
| 900 | PLIST_XML_ERR("Unexpected tag %s found while /plist is expected\n", tag); | ||
| 901 | ctx->err++; | ||
| 902 | free(tag); | ||
| 903 | free(keyname); | ||
| 904 | return; | ||
| 892 | } | 905 | } |
| 893 | 906 | ||
| 894 | plist_data_t data = plist_new_plist_data(); | 907 | plist_data_t data = plist_new_plist_data(); |
| @@ -1128,7 +1141,7 @@ static void node_from_xml(parse_ctx ctx, plist_t *plist) | |||
| 1128 | if (data->type == PLIST_DICT || data->type == PLIST_ARRAY) { | 1141 | if (data->type == PLIST_DICT || data->type == PLIST_ARRAY) { |
| 1129 | if (!is_empty) { | 1142 | if (!is_empty) { |
| 1130 | /* only if not empty */ | 1143 | /* only if not empty */ |
| 1131 | node_from_xml(ctx, &subnode); | 1144 | node_from_xml(ctx, &subnode, depth+1); |
| 1132 | if (ctx->err) { | 1145 | if (ctx->err) { |
| 1133 | /* make sure to bail out if parsing failed */ | 1146 | /* make sure to bail out if parsing failed */ |
| 1134 | free(keyname); | 1147 | free(keyname); |
| @@ -1176,9 +1189,30 @@ static void node_from_xml(parse_ctx ctx, plist_t *plist) | |||
| 1176 | break; | 1189 | break; |
| 1177 | } | 1190 | } |
| 1178 | } | 1191 | } |
| 1179 | } else if (closing_tag && *plist && plist_get_node_type(*plist) == PLIST_DICT && keyname) { | 1192 | } else if (closing_tag && *plist) { |
| 1180 | PLIST_XML_ERR("missing value node in dict\n"); | 1193 | switch (plist_get_node_type(*plist)) { |
| 1181 | ctx->err++; | 1194 | case PLIST_DICT: |
| 1195 | if (keyname) { | ||
| 1196 | PLIST_XML_ERR("missing value node in dict\n"); | ||
| 1197 | ctx->err++; | ||
| 1198 | } else if (strcmp(tag+1, XPLIST_DICT) != 0) { | ||
| 1199 | PLIST_XML_ERR("closing tag mismatch, expected: /%s found: %s\n", XPLIST_DICT, tag); | ||
| 1200 | ctx->err++; | ||
| 1201 | } | ||
| 1202 | break; | ||
| 1203 | case PLIST_ARRAY: | ||
| 1204 | if (strcmp(tag+1, XPLIST_ARRAY) != 0) { | ||
| 1205 | PLIST_XML_ERR("closing tag mismatch, expected: /%s found: %s\n", XPLIST_ARRAY, tag); | ||
| 1206 | ctx->err++; | ||
| 1207 | } | ||
| 1208 | break; | ||
| 1209 | default: | ||
| 1210 | /* should not happen */ | ||
| 1211 | PLIST_XML_ERR("expected structered node but got type %d\n", plist_get_node_type(*plist)); | ||
| 1212 | ctx->err++; | ||
| 1213 | break; | ||
| 1214 | } | ||
| 1215 | break; | ||
| 1182 | } | 1216 | } |
| 1183 | free(keyname); | 1217 | free(keyname); |
| 1184 | keyname = NULL; | 1218 | keyname = NULL; |
| @@ -1188,6 +1222,10 @@ static void node_from_xml(parse_ctx ctx, plist_t *plist) | |||
| 1188 | } | 1222 | } |
| 1189 | } | 1223 | } |
| 1190 | } | 1224 | } |
| 1225 | if (depth == 1) { | ||
| 1226 | PLIST_XML_ERR("EOF while /plist tag is expected\n"); | ||
| 1227 | ctx->err++; | ||
| 1228 | } | ||
| 1191 | if (ctx->err) { | 1229 | if (ctx->err) { |
| 1192 | plist_free(*plist); | 1230 | plist_free(*plist); |
| 1193 | *plist = NULL; | 1231 | *plist = NULL; |
| @@ -1203,5 +1241,5 @@ PLIST_API void plist_from_xml(const char *plist_xml, uint32_t length, plist_t * | |||
| 1203 | 1241 | ||
| 1204 | struct _parse_ctx ctx = { plist_xml, plist_xml + length, 0 }; | 1242 | struct _parse_ctx ctx = { plist_xml, plist_xml + length, 0 }; |
| 1205 | 1243 | ||
| 1206 | node_from_xml(&ctx, plist); | 1244 | node_from_xml(&ctx, plist, 0); |
| 1207 | } | 1245 | } |
