summaryrefslogtreecommitdiffstats
path: root/src/xplist.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/xplist.c')
-rw-r--r--src/xplist.c111
1 files changed, 62 insertions, 49 deletions
diff --git a/src/xplist.c b/src/xplist.c
index c25c6b9..9870104 100644
--- a/src/xplist.c
+++ b/src/xplist.c
@@ -452,6 +452,11 @@ static plist_err_t _node_estimate_size(node_t node, uint64_t *size, uint32_t dep
452 return PLIST_ERR_INVALID_ARG; 452 return PLIST_ERR_INVALID_ARG;
453 } 453 }
454 454
455 if (depth > PLIST_MAX_NESTING_DEPTH) {
456 PLIST_XML_WRITE_ERR("maximum nesting depth (%u) exceeded\n", (unsigned)PLIST_MAX_NESTING_DEPTH);
457 return PLIST_ERR_MAX_NESTING;
458 }
459
455 if (hash_table_lookup(visited, node)) { 460 if (hash_table_lookup(visited, node)) {
456 PLIST_XML_WRITE_ERR("circular reference detected\n"); 461 PLIST_XML_WRITE_ERR("circular reference detected\n");
457 return PLIST_ERR_CIRCULAR_REF; 462 return PLIST_ERR_CIRCULAR_REF;
@@ -596,7 +601,7 @@ plist_err_t plist_to_xml(plist_t plist, char **plist_xml, uint32_t * length)
596struct _parse_ctx { 601struct _parse_ctx {
597 const char *pos; 602 const char *pos;
598 const char *end; 603 const char *end;
599 int err; 604 plist_err_t err;
600}; 605};
601typedef struct _parse_ctx* parse_ctx; 606typedef struct _parse_ctx* parse_ctx;
602 607
@@ -720,21 +725,21 @@ static text_part_t* get_text_parts(parse_ctx ctx, const char* tag, size_t tag_le
720 find_char(ctx, '<', 0); 725 find_char(ctx, '<', 0);
721 if (ctx->pos >= ctx->end || *ctx->pos != '<') { 726 if (ctx->pos >= ctx->end || *ctx->pos != '<') {
722 PLIST_XML_ERR("EOF while looking for closing tag\n"); 727 PLIST_XML_ERR("EOF while looking for closing tag\n");
723 ctx->err++; 728 ctx->err = PLIST_ERR_PARSE;
724 return NULL; 729 return NULL;
725 } 730 }
726 q = ctx->pos; 731 q = ctx->pos;
727 ctx->pos++; 732 ctx->pos++;
728 if (ctx->pos >= ctx->end) { 733 if (ctx->pos >= ctx->end) {
729 PLIST_XML_ERR("EOF while parsing '%s'\n", p); 734 PLIST_XML_ERR("EOF while parsing '%s'\n", p);
730 ctx->err++; 735 ctx->err = PLIST_ERR_PARSE;
731 return NULL; 736 return NULL;
732 } 737 }
733 if (*ctx->pos == '!') { 738 if (*ctx->pos == '!') {
734 ctx->pos++; 739 ctx->pos++;
735 if (ctx->pos >= ctx->end-1) { 740 if (ctx->pos >= ctx->end-1) {
736 PLIST_XML_ERR("EOF while parsing <! special tag\n"); 741 PLIST_XML_ERR("EOF while parsing <! special tag\n");
737 ctx->err++; 742 ctx->err = PLIST_ERR_PARSE;
738 return NULL; 743 return NULL;
739 } 744 }
740 if (*ctx->pos == '-' && *(ctx->pos+1) == '-') { 745 if (*ctx->pos == '-' && *(ctx->pos+1) == '-') {
@@ -747,7 +752,7 @@ static text_part_t* get_text_parts(parse_ctx ctx, const char* tag, size_t tag_le
747 find_str(ctx, "-->", 3, 0); 752 find_str(ctx, "-->", 3, 0);
748 if (ctx->pos > ctx->end-3 || strncmp(ctx->pos, "-->", 3) != 0) { 753 if (ctx->pos > ctx->end-3 || strncmp(ctx->pos, "-->", 3) != 0) {
749 PLIST_XML_ERR("EOF while looking for end of comment\n"); 754 PLIST_XML_ERR("EOF while looking for end of comment\n");
750 ctx->err++; 755 ctx->err = PLIST_ERR_PARSE;
751 return NULL; 756 return NULL;
752 } 757 }
753 ctx->pos += 3; 758 ctx->pos += 3;
@@ -755,7 +760,7 @@ static text_part_t* get_text_parts(parse_ctx ctx, const char* tag, size_t tag_le
755 ctx->pos++; 760 ctx->pos++;
756 if (ctx->pos >= ctx->end - 8) { 761 if (ctx->pos >= ctx->end - 8) {
757 PLIST_XML_ERR("EOF while parsing <[ tag\n"); 762 PLIST_XML_ERR("EOF while parsing <[ tag\n");
758 ctx->err++; 763 ctx->err = PLIST_ERR_PARSE;
759 return NULL; 764 return NULL;
760 } 765 }
761 if (strncmp(ctx->pos, "CDATA[", 6) == 0) { 766 if (strncmp(ctx->pos, "CDATA[", 6) == 0) {
@@ -771,7 +776,7 @@ static text_part_t* get_text_parts(parse_ctx ctx, const char* tag, size_t tag_le
771 find_str(ctx, "]]>", 3, 0); 776 find_str(ctx, "]]>", 3, 0);
772 if (ctx->pos > ctx->end-3 || strncmp(ctx->pos, "]]>", 3) != 0) { 777 if (ctx->pos > ctx->end-3 || strncmp(ctx->pos, "]]>", 3) != 0) {
773 PLIST_XML_ERR("EOF while looking for end of CDATA block\n"); 778 PLIST_XML_ERR("EOF while looking for end of CDATA block\n");
774 ctx->err++; 779 ctx->err = PLIST_ERR_PARSE;
775 return NULL; 780 return NULL;
776 } 781 }
777 q = ctx->pos; 782 q = ctx->pos;
@@ -785,14 +790,14 @@ static text_part_t* get_text_parts(parse_ctx ctx, const char* tag, size_t tag_le
785 p = ctx->pos; 790 p = ctx->pos;
786 find_next(ctx, " \r\n\t>", 5, 1); 791 find_next(ctx, " \r\n\t>", 5, 1);
787 PLIST_XML_ERR("Invalid special tag <[%.*s> encountered inside <%s> tag\n", (int)(ctx->pos - p), p, tag); 792 PLIST_XML_ERR("Invalid special tag <[%.*s> encountered inside <%s> tag\n", (int)(ctx->pos - p), p, tag);
788 ctx->err++; 793 ctx->err = PLIST_ERR_PARSE;
789 return NULL; 794 return NULL;
790 } 795 }
791 } else { 796 } else {
792 p = ctx->pos; 797 p = ctx->pos;
793 find_next(ctx, " \r\n\t>", 5, 1); 798 find_next(ctx, " \r\n\t>", 5, 1);
794 PLIST_XML_ERR("Invalid special tag <!%.*s> encountered inside <%s> tag\n", (int)(ctx->pos - p), p, tag); 799 PLIST_XML_ERR("Invalid special tag <!%.*s> encountered inside <%s> tag\n", (int)(ctx->pos - p), p, tag);
795 ctx->err++; 800 ctx->err = PLIST_ERR_PARSE;
796 return NULL; 801 return NULL;
797 } 802 }
798 } else if (*ctx->pos == '/') { 803 } else if (*ctx->pos == '/') {
@@ -801,25 +806,25 @@ static text_part_t* get_text_parts(parse_ctx ctx, const char* tag, size_t tag_le
801 p = ctx->pos; 806 p = ctx->pos;
802 find_next(ctx, " \r\n\t>", 5, 1); 807 find_next(ctx, " \r\n\t>", 5, 1);
803 PLIST_XML_ERR("Invalid tag <%.*s> encountered inside <%s> tag\n", (int)(ctx->pos - p), p, tag); 808 PLIST_XML_ERR("Invalid tag <%.*s> encountered inside <%s> tag\n", (int)(ctx->pos - p), p, tag);
804 ctx->err++; 809 ctx->err = PLIST_ERR_PARSE;
805 return NULL; 810 return NULL;
806 } 811 }
807 } while (1); 812 } while (1);
808 ctx->pos++; 813 ctx->pos++;
809 if (ctx->pos >= ctx->end-tag_len || strncmp(ctx->pos, tag, tag_len) != 0) { 814 if (ctx->pos >= ctx->end-tag_len || strncmp(ctx->pos, tag, tag_len) != 0) {
810 PLIST_XML_ERR("EOF or end tag mismatch\n"); 815 PLIST_XML_ERR("EOF or end tag mismatch\n");
811 ctx->err++; 816 ctx->err = PLIST_ERR_PARSE;
812 return NULL; 817 return NULL;
813 } 818 }
814 ctx->pos+=tag_len; 819 ctx->pos+=tag_len;
815 parse_skip_ws(ctx); 820 parse_skip_ws(ctx);
816 if (ctx->pos >= ctx->end) { 821 if (ctx->pos >= ctx->end) {
817 PLIST_XML_ERR("EOF while parsing closing tag\n"); 822 PLIST_XML_ERR("EOF while parsing closing tag\n");
818 ctx->err++; 823 ctx->err = PLIST_ERR_PARSE;
819 return NULL; 824 return NULL;
820 } else if (*ctx->pos != '>') { 825 } else if (*ctx->pos != '>') {
821 PLIST_XML_ERR("Invalid closing tag; expected '>', found '%c'\n", *ctx->pos); 826 PLIST_XML_ERR("Invalid closing tag; expected '>', found '%c'\n", *ctx->pos);
822 ctx->err++; 827 ctx->err = PLIST_ERR_PARSE;
823 return NULL; 828 return NULL;
824 } 829 }
825 ctx->pos++; 830 ctx->pos++;
@@ -995,6 +1000,7 @@ static plist_err_t node_from_xml(parse_ctx ctx, plist_t *plist)
995 void *prev; 1000 void *prev;
996 }; 1001 };
997 struct node_path_item* node_path = NULL; 1002 struct node_path_item* node_path = NULL;
1003 int depth = 0;
998 1004
999 while (ctx->pos < ctx->end && !ctx->err) { 1005 while (ctx->pos < ctx->end && !ctx->err) {
1000 parse_skip_ws(ctx); 1006 parse_skip_ws(ctx);
@@ -1005,13 +1011,13 @@ static plist_err_t node_from_xml(parse_ctx ctx, plist_t *plist)
1005 p = ctx->pos; 1011 p = ctx->pos;
1006 find_next(ctx, " \t\r\n", 4, 0); 1012 find_next(ctx, " \t\r\n", 4, 0);
1007 PLIST_XML_ERR("Expected: opening tag, found: %.*s\n", (int)(ctx->pos - p), p); 1013 PLIST_XML_ERR("Expected: opening tag, found: %.*s\n", (int)(ctx->pos - p), p);
1008 ctx->err++; 1014 ctx->err = PLIST_ERR_PARSE;
1009 goto err_out; 1015 goto err_out;
1010 } 1016 }
1011 ctx->pos++; 1017 ctx->pos++;
1012 if (ctx->pos >= ctx->end) { 1018 if (ctx->pos >= ctx->end) {
1013 PLIST_XML_ERR("EOF while parsing tag\n"); 1019 PLIST_XML_ERR("EOF while parsing tag\n");
1014 ctx->err++; 1020 ctx->err = PLIST_ERR_PARSE;
1015 goto err_out; 1021 goto err_out;
1016 } 1022 }
1017 1023
@@ -1019,12 +1025,12 @@ static plist_err_t node_from_xml(parse_ctx ctx, plist_t *plist)
1019 find_str(ctx, "?>", 2, 1); 1025 find_str(ctx, "?>", 2, 1);
1020 if (ctx->pos > ctx->end-2) { 1026 if (ctx->pos > ctx->end-2) {
1021 PLIST_XML_ERR("EOF while looking for <? tag closing marker\n"); 1027 PLIST_XML_ERR("EOF while looking for <? tag closing marker\n");
1022 ctx->err++; 1028 ctx->err = PLIST_ERR_PARSE;
1023 goto err_out; 1029 goto err_out;
1024 } 1030 }
1025 if (strncmp(ctx->pos, "?>", 2) != 0) { 1031 if (strncmp(ctx->pos, "?>", 2) != 0) {
1026 PLIST_XML_ERR("Couldn't find <? tag closing marker\n"); 1032 PLIST_XML_ERR("Couldn't find <? tag closing marker\n");
1027 ctx->err++; 1033 ctx->err = PLIST_ERR_PARSE;
1028 goto err_out; 1034 goto err_out;
1029 } 1035 }
1030 ctx->pos += 2; 1036 ctx->pos += 2;
@@ -1036,7 +1042,7 @@ static plist_err_t node_from_xml(parse_ctx ctx, plist_t *plist)
1036 find_str(ctx,"-->", 3, 0); 1042 find_str(ctx,"-->", 3, 0);
1037 if (ctx->pos > ctx->end-3 || strncmp(ctx->pos, "-->", 3) != 0) { 1043 if (ctx->pos > ctx->end-3 || strncmp(ctx->pos, "-->", 3) != 0) {
1038 PLIST_XML_ERR("Couldn't find end of comment\n"); 1044 PLIST_XML_ERR("Couldn't find end of comment\n");
1039 ctx->err++; 1045 ctx->err = PLIST_ERR_PARSE;
1040 goto err_out; 1046 goto err_out;
1041 } 1047 }
1042 ctx->pos+=3; 1048 ctx->pos+=3;
@@ -1047,7 +1053,7 @@ static plist_err_t node_from_xml(parse_ctx ctx, plist_t *plist)
1047 find_next(ctx, " \t\r\n[>", 6, 1); 1053 find_next(ctx, " \t\r\n[>", 6, 1);
1048 if (ctx->pos >= ctx->end) { 1054 if (ctx->pos >= ctx->end) {
1049 PLIST_XML_ERR("EOF while parsing !DOCTYPE\n"); 1055 PLIST_XML_ERR("EOF while parsing !DOCTYPE\n");
1050 ctx->err++; 1056 ctx->err = PLIST_ERR_PARSE;
1051 goto err_out; 1057 goto err_out;
1052 } 1058 }
1053 if (*ctx->pos == '[') { 1059 if (*ctx->pos == '[') {
@@ -1065,7 +1071,7 @@ static plist_err_t node_from_xml(parse_ctx ctx, plist_t *plist)
1065 find_str(ctx, "]>", 2, 1); 1071 find_str(ctx, "]>", 2, 1);
1066 if (ctx->pos > ctx->end-2 || strncmp(ctx->pos, "]>", 2) != 0) { 1072 if (ctx->pos > ctx->end-2 || strncmp(ctx->pos, "]>", 2) != 0) {
1067 PLIST_XML_ERR("Couldn't find end of DOCTYPE\n"); 1073 PLIST_XML_ERR("Couldn't find end of DOCTYPE\n");
1068 ctx->err++; 1074 ctx->err = PLIST_ERR_PARSE;
1069 goto err_out; 1075 goto err_out;
1070 } 1076 }
1071 ctx->pos += 2; 1077 ctx->pos += 2;
@@ -1074,7 +1080,7 @@ static plist_err_t node_from_xml(parse_ctx ctx, plist_t *plist)
1074 p = ctx->pos; 1080 p = ctx->pos;
1075 find_next(ctx, " \r\n\t>", 5, 1); 1081 find_next(ctx, " \r\n\t>", 5, 1);
1076 PLIST_XML_ERR("Invalid or incomplete special tag <%.*s> encountered\n", (int)(ctx->pos - p), p); 1082 PLIST_XML_ERR("Invalid or incomplete special tag <%.*s> encountered\n", (int)(ctx->pos - p), p);
1077 ctx->err++; 1083 ctx->err = PLIST_ERR_PARSE;
1078 goto err_out; 1084 goto err_out;
1079 } 1085 }
1080 continue; 1086 continue;
@@ -1085,7 +1091,7 @@ static plist_err_t node_from_xml(parse_ctx ctx, plist_t *plist)
1085 find_next(ctx," \r\n\t<>", 6, 0); 1091 find_next(ctx," \r\n\t<>", 6, 0);
1086 if (ctx->pos >= ctx->end) { 1092 if (ctx->pos >= ctx->end) {
1087 PLIST_XML_ERR("Unexpected EOF while parsing XML\n"); 1093 PLIST_XML_ERR("Unexpected EOF while parsing XML\n");
1088 ctx->err++; 1094 ctx->err = PLIST_ERR_PARSE;
1089 goto err_out; 1095 goto err_out;
1090 } 1096 }
1091 size_t taglen = ctx->pos - p; 1097 size_t taglen = ctx->pos - p;
@@ -1097,12 +1103,12 @@ static plist_err_t node_from_xml(parse_ctx ctx, plist_t *plist)
1097 } 1103 }
1098 if (ctx->pos >= ctx->end) { 1104 if (ctx->pos >= ctx->end) {
1099 PLIST_XML_ERR("Unexpected EOF while parsing XML\n"); 1105 PLIST_XML_ERR("Unexpected EOF while parsing XML\n");
1100 ctx->err++; 1106 ctx->err = PLIST_ERR_PARSE;
1101 goto err_out; 1107 goto err_out;
1102 } 1108 }
1103 if (*ctx->pos != '>') { 1109 if (*ctx->pos != '>') {
1104 PLIST_XML_ERR("Missing '>' for tag <%s\n", tag); 1110 PLIST_XML_ERR("Missing '>' for tag <%s\n", tag);
1105 ctx->err++; 1111 ctx->err = PLIST_ERR_PARSE;
1106 goto err_out; 1112 goto err_out;
1107 } 1113 }
1108 if (*(ctx->pos-1) == '/') { 1114 if (*(ctx->pos-1) == '/') {
@@ -1123,14 +1129,14 @@ static plist_err_t node_from_xml(parse_ctx ctx, plist_t *plist)
1123 } 1129 }
1124 if (is_empty) { 1130 if (is_empty) {
1125 PLIST_XML_ERR("Empty plist tag\n"); 1131 PLIST_XML_ERR("Empty plist tag\n");
1126 ctx->err++; 1132 ctx->err = PLIST_ERR_PARSE;
1127 goto err_out; 1133 goto err_out;
1128 } 1134 }
1129 1135
1130 struct node_path_item *path_item = (struct node_path_item*)malloc(sizeof(struct node_path_item)); 1136 struct node_path_item *path_item = (struct node_path_item*)malloc(sizeof(struct node_path_item));
1131 if (!path_item) { 1137 if (!path_item) {
1132 PLIST_XML_ERR("out of memory when allocating node path item\n"); 1138 PLIST_XML_ERR("out of memory when allocating node path item\n");
1133 ctx->err++; 1139 ctx->err = PLIST_ERR_PARSE;
1134 goto err_out; 1140 goto err_out;
1135 } 1141 }
1136 path_item->type = "plist"; 1142 path_item->type = "plist";
@@ -1141,17 +1147,17 @@ static plist_err_t node_from_xml(parse_ctx ctx, plist_t *plist)
1141 } else if (!strcmp(tag, "/plist")) { 1147 } else if (!strcmp(tag, "/plist")) {
1142 if (!has_content) { 1148 if (!has_content) {
1143 PLIST_XML_ERR("encountered empty plist tag\n"); 1149 PLIST_XML_ERR("encountered empty plist tag\n");
1144 ctx->err++; 1150 ctx->err = PLIST_ERR_PARSE;
1145 goto err_out; 1151 goto err_out;
1146 } 1152 }
1147 if (!node_path) { 1153 if (!node_path) {
1148 PLIST_XML_ERR("node path is empty while trying to match closing tag with opening tag\n"); 1154 PLIST_XML_ERR("node path is empty while trying to match closing tag with opening tag\n");
1149 ctx->err++; 1155 ctx->err = PLIST_ERR_PARSE;
1150 goto err_out; 1156 goto err_out;
1151 } 1157 }
1152 if (strcmp(node_path->type, tag+1) != 0) { 1158 if (strcmp(node_path->type, tag+1) != 0) {
1153 PLIST_XML_ERR("mismatching closing tag <%s> found for opening tag <%s>\n", tag, node_path->type); 1159 PLIST_XML_ERR("mismatching closing tag <%s> found for opening tag <%s>\n", tag, node_path->type);
1154 ctx->err++; 1160 ctx->err = PLIST_ERR_PARSE;
1155 goto err_out; 1161 goto err_out;
1156 } 1162 }
1157 struct node_path_item *path_item = node_path; 1163 struct node_path_item *path_item = node_path;
@@ -1179,7 +1185,7 @@ static plist_err_t node_from_xml(parse_ctx ctx, plist_t *plist)
1179 if (!tp) { 1185 if (!tp) {
1180 PLIST_XML_ERR("Could not parse text content for '%s' node\n", tag); 1186 PLIST_XML_ERR("Could not parse text content for '%s' node\n", tag);
1181 text_parts_free((text_part_t*)first_part.next); 1187 text_parts_free((text_part_t*)first_part.next);
1182 ctx->err++; 1188 ctx->err = PLIST_ERR_PARSE;
1183 goto err_out; 1189 goto err_out;
1184 } 1190 }
1185 if (tp->begin) { 1191 if (tp->begin) {
@@ -1188,7 +1194,7 @@ static plist_err_t node_from_xml(parse_ctx ctx, plist_t *plist)
1188 if (!str_content) { 1194 if (!str_content) {
1189 PLIST_XML_ERR("Could not get text content for '%s' node\n", tag); 1195 PLIST_XML_ERR("Could not get text content for '%s' node\n", tag);
1190 text_parts_free((text_part_t*)first_part.next); 1196 text_parts_free((text_part_t*)first_part.next);
1191 ctx->err++; 1197 ctx->err = PLIST_ERR_PARSE;
1192 goto err_out; 1198 goto err_out;
1193 } 1199 }
1194 char *str = str_content; 1200 char *str = str_content;
@@ -1230,7 +1236,7 @@ static plist_err_t node_from_xml(parse_ctx ctx, plist_t *plist)
1230 if (!tp) { 1236 if (!tp) {
1231 PLIST_XML_ERR("Could not parse text content for '%s' node\n", tag); 1237 PLIST_XML_ERR("Could not parse text content for '%s' node\n", tag);
1232 text_parts_free((text_part_t*)first_part.next); 1238 text_parts_free((text_part_t*)first_part.next);
1233 ctx->err++; 1239 ctx->err = PLIST_ERR_PARSE;
1234 goto err_out; 1240 goto err_out;
1235 } 1241 }
1236 if (tp->begin) { 1242 if (tp->begin) {
@@ -1239,7 +1245,7 @@ static plist_err_t node_from_xml(parse_ctx ctx, plist_t *plist)
1239 if (!str_content) { 1245 if (!str_content) {
1240 PLIST_XML_ERR("Could not get text content for '%s' node\n", tag); 1246 PLIST_XML_ERR("Could not get text content for '%s' node\n", tag);
1241 text_parts_free((text_part_t*)first_part.next); 1247 text_parts_free((text_part_t*)first_part.next);
1242 ctx->err++; 1248 ctx->err = PLIST_ERR_PARSE;
1243 goto err_out; 1249 goto err_out;
1244 } 1250 }
1245 data->realval = atof(str_content); 1251 data->realval = atof(str_content);
@@ -1274,14 +1280,14 @@ static plist_err_t node_from_xml(parse_ctx ctx, plist_t *plist)
1274 if (!tp) { 1280 if (!tp) {
1275 PLIST_XML_ERR("Could not parse text content for '%s' node\n", tag); 1281 PLIST_XML_ERR("Could not parse text content for '%s' node\n", tag);
1276 text_parts_free((text_part_t*)first_part.next); 1282 text_parts_free((text_part_t*)first_part.next);
1277 ctx->err++; 1283 ctx->err = PLIST_ERR_PARSE;
1278 goto err_out; 1284 goto err_out;
1279 } 1285 }
1280 str = text_parts_get_content(tp, 1, &length, NULL); 1286 str = text_parts_get_content(tp, 1, &length, NULL);
1281 text_parts_free((text_part_t*)first_part.next); 1287 text_parts_free((text_part_t*)first_part.next);
1282 if (!str) { 1288 if (!str) {
1283 PLIST_XML_ERR("Could not get text content for '%s' node\n", tag); 1289 PLIST_XML_ERR("Could not get text content for '%s' node\n", tag);
1284 ctx->err++; 1290 ctx->err = PLIST_ERR_PARSE;
1285 goto err_out; 1291 goto err_out;
1286 } 1292 }
1287 if (!strcmp(tag, "key") && !keyname && parent && (plist_get_node_type(parent) == PLIST_DICT)) { 1293 if (!strcmp(tag, "key") && !keyname && parent && (plist_get_node_type(parent) == PLIST_DICT)) {
@@ -1315,7 +1321,7 @@ static plist_err_t node_from_xml(parse_ctx ctx, plist_t *plist)
1315 if (!tp) { 1321 if (!tp) {
1316 PLIST_XML_ERR("Could not parse text content for '%s' node\n", tag); 1322 PLIST_XML_ERR("Could not parse text content for '%s' node\n", tag);
1317 text_parts_free((text_part_t*)first_part.next); 1323 text_parts_free((text_part_t*)first_part.next);
1318 ctx->err++; 1324 ctx->err = PLIST_ERR_PARSE;
1319 goto err_out; 1325 goto err_out;
1320 } 1326 }
1321 if (tp->begin) { 1327 if (tp->begin) {
@@ -1324,7 +1330,7 @@ static plist_err_t node_from_xml(parse_ctx ctx, plist_t *plist)
1324 if (!str_content) { 1330 if (!str_content) {
1325 PLIST_XML_ERR("Could not get text content for '%s' node\n", tag); 1331 PLIST_XML_ERR("Could not get text content for '%s' node\n", tag);
1326 text_parts_free((text_part_t*)first_part.next); 1332 text_parts_free((text_part_t*)first_part.next);
1327 ctx->err++; 1333 ctx->err = PLIST_ERR_PARSE;
1328 goto err_out; 1334 goto err_out;
1329 } 1335 }
1330 size_t size = tp->length; 1336 size_t size = tp->length;
@@ -1347,7 +1353,7 @@ static plist_err_t node_from_xml(parse_ctx ctx, plist_t *plist)
1347 if (!tp) { 1353 if (!tp) {
1348 PLIST_XML_ERR("Could not parse text content for '%s' node\n", tag); 1354 PLIST_XML_ERR("Could not parse text content for '%s' node\n", tag);
1349 text_parts_free((text_part_t*)first_part.next); 1355 text_parts_free((text_part_t*)first_part.next);
1350 ctx->err++; 1356 ctx->err = PLIST_ERR_PARSE;
1351 goto err_out; 1357 goto err_out;
1352 } 1358 }
1353 Time64_T timev = 0; 1359 Time64_T timev = 0;
@@ -1358,7 +1364,7 @@ static plist_err_t node_from_xml(parse_ctx ctx, plist_t *plist)
1358 if (!str_content) { 1364 if (!str_content) {
1359 PLIST_XML_ERR("Could not get text content for '%s' node\n", tag); 1365 PLIST_XML_ERR("Could not get text content for '%s' node\n", tag);
1360 text_parts_free((text_part_t*)first_part.next); 1366 text_parts_free((text_part_t*)first_part.next);
1361 ctx->err++; 1367 ctx->err = PLIST_ERR_PARSE;
1362 goto err_out; 1368 goto err_out;
1363 } 1369 }
1364 1370
@@ -1387,7 +1393,7 @@ static plist_err_t node_from_xml(parse_ctx ctx, plist_t *plist)
1387 } else { 1393 } else {
1388 PLIST_XML_ERR("Unexpected tag <%s%s> encountered\n", tag, (is_empty) ? "/" : ""); 1394 PLIST_XML_ERR("Unexpected tag <%s%s> encountered\n", tag, (is_empty) ? "/" : "");
1389 ctx->pos = ctx->end; 1395 ctx->pos = ctx->end;
1390 ctx->err++; 1396 ctx->err = PLIST_ERR_PARSE;
1391 goto err_out; 1397 goto err_out;
1392 } 1398 }
1393 if (subnode && !closing_tag) { 1399 if (subnode && !closing_tag) {
@@ -1405,7 +1411,7 @@ static plist_err_t node_from_xml(parse_ctx ctx, plist_t *plist)
1405 case PLIST_DICT: 1411 case PLIST_DICT:
1406 if (!keyname) { 1412 if (!keyname) {
1407 PLIST_XML_ERR("missing key name while adding dict item\n"); 1413 PLIST_XML_ERR("missing key name while adding dict item\n");
1408 ctx->err++; 1414 ctx->err = PLIST_ERR_PARSE;
1409 goto err_out; 1415 goto err_out;
1410 } 1416 }
1411 plist_dict_set_item(parent, keyname, subnode); 1417 plist_dict_set_item(parent, keyname, subnode);
@@ -1416,35 +1422,42 @@ static plist_err_t node_from_xml(parse_ctx ctx, plist_t *plist)
1416 default: 1422 default:
1417 /* should not happen */ 1423 /* should not happen */
1418 PLIST_XML_ERR("parent is not a structured node\n"); 1424 PLIST_XML_ERR("parent is not a structured node\n");
1419 ctx->err++; 1425 ctx->err = PLIST_ERR_PARSE;
1420 goto err_out; 1426 goto err_out;
1421 } 1427 }
1422 } 1428 }
1423 if (!is_empty && (data->type == PLIST_DICT || data->type == PLIST_ARRAY)) { 1429 if (!is_empty && (data->type == PLIST_DICT || data->type == PLIST_ARRAY)) {
1430 if (depth >= PLIST_MAX_NESTING_DEPTH) {
1431 PLIST_XML_ERR("maximum nesting depth (%u) exceeded\n", (unsigned)PLIST_MAX_NESTING_DEPTH);
1432 ctx->err = PLIST_ERR_MAX_NESTING;
1433 goto err_out;
1434 }
1424 struct node_path_item *path_item = (struct node_path_item*)malloc(sizeof(struct node_path_item)); 1435 struct node_path_item *path_item = (struct node_path_item*)malloc(sizeof(struct node_path_item));
1425 if (!path_item) { 1436 if (!path_item) {
1426 PLIST_XML_ERR("out of memory when allocating node path item\n"); 1437 PLIST_XML_ERR("out of memory when allocating node path item\n");
1427 ctx->err++; 1438 ctx->err = PLIST_ERR_PARSE;
1428 goto err_out; 1439 goto err_out;
1429 } 1440 }
1430 path_item->type = (data->type == PLIST_DICT) ? XPLIST_DICT : XPLIST_ARRAY; 1441 path_item->type = (data->type == PLIST_DICT) ? XPLIST_DICT : XPLIST_ARRAY;
1431 path_item->prev = node_path; 1442 path_item->prev = node_path;
1432 node_path = path_item; 1443 node_path = path_item;
1433 1444
1445 depth++;
1434 parent = subnode; 1446 parent = subnode;
1435 } 1447 }
1436 subnode = NULL; 1448 subnode = NULL;
1437 } else if (closing_tag) { 1449 } else if (closing_tag) {
1438 if (!node_path) { 1450 if (!node_path) {
1439 PLIST_XML_ERR("node path is empty while trying to match closing tag with opening tag\n"); 1451 PLIST_XML_ERR("node path is empty while trying to match closing tag with opening tag\n");
1440 ctx->err++; 1452 ctx->err = PLIST_ERR_PARSE;
1441 goto err_out; 1453 goto err_out;
1442 } 1454 }
1443 if (strcmp(node_path->type, tag+1) != 0) { 1455 if (strcmp(node_path->type, tag+1) != 0) {
1444 PLIST_XML_ERR("unexpected %s found (for opening %s)\n", tag, node_path->type); 1456 PLIST_XML_ERR("unexpected %s found (for opening %s)\n", tag, node_path->type);
1445 ctx->err++; 1457 ctx->err = PLIST_ERR_PARSE;
1446 goto err_out; 1458 goto err_out;
1447 } 1459 }
1460 if (depth > 0) depth--;
1448 struct node_path_item *path_item = node_path; 1461 struct node_path_item *path_item = node_path;
1449 node_path = (struct node_path_item*)node_path->prev; 1462 node_path = (struct node_path_item*)node_path->prev;
1450 free(path_item); 1463 free(path_item);
@@ -1466,7 +1479,7 @@ static plist_err_t node_from_xml(parse_ctx ctx, plist_t *plist)
1466 1479
1467 if (node_path) { 1480 if (node_path) {
1468 PLIST_XML_ERR("EOF encountered while </%s> was expected\n", node_path->type); 1481 PLIST_XML_ERR("EOF encountered while </%s> was expected\n", node_path->type);
1469 ctx->err++; 1482 ctx->err = PLIST_ERR_PARSE;
1470 } 1483 }
1471 1484
1472err_out: 1485err_out:
@@ -1481,10 +1494,10 @@ err_out:
1481 free(path_item); 1494 free(path_item);
1482 } 1495 }
1483 1496
1484 if (ctx->err) { 1497 if (ctx->err != PLIST_ERR_SUCCESS) {
1485 plist_free(*plist); 1498 plist_free(*plist);
1486 *plist = NULL; 1499 *plist = NULL;
1487 return PLIST_ERR_PARSE; 1500 return ctx->err;
1488 } 1501 }
1489 1502
1490 /* check if we have a UID "dict" so we can replace it with a proper UID node */ 1503 /* check if we have a UID "dict" so we can replace it with a proper UID node */
@@ -1511,7 +1524,7 @@ plist_err_t plist_from_xml(const char *plist_xml, uint32_t length, plist_t * pli
1511 return PLIST_ERR_INVALID_ARG; 1524 return PLIST_ERR_INVALID_ARG;
1512 } 1525 }
1513 1526
1514 struct _parse_ctx ctx = { plist_xml, plist_xml + length, 0 }; 1527 struct _parse_ctx ctx = { plist_xml, plist_xml + length, PLIST_ERR_SUCCESS };
1515 1528
1516 return node_from_xml(&ctx, plist); 1529 return node_from_xml(&ctx, plist);
1517} 1530}