summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGravatar Nikias Bassen2016-12-21 03:46:02 +0100
committerGravatar Nikias Bassen2016-12-21 03:46:02 +0100
commitd98ef4146e4e796e267284f37e06c86e75fcf30f (patch)
tree3d109c97e570a3e801a30bee980321348fb5b596 /src
parent793228208a6523bdbe434ed536c5669e4bb04f7c (diff)
downloadlibplist-d98ef4146e4e796e267284f37e06c86e75fcf30f.tar.gz
libplist-d98ef4146e4e796e267284f37e06c86e75fcf30f.tar.bz2
xplist: Make sure to correctly parse for closing tags of structured nodes
Diffstat (limited to 'src')
-rw-r--r--src/xplist.c52
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
765static void node_from_xml(parse_ctx ctx, plist_t *plist) 765static 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}