summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Nikias Bassen2017-02-06 20:02:39 +0100
committerGravatar Nikias Bassen2017-02-06 20:02:39 +0100
commit35fdf8e73b9ee75b880cb9ff2de5491d7ddae20b (patch)
tree3209a50fdf1b2a53ffd4c0d93ebf81018dfaee2b
parentc98451f9eabb68df3dfabaedc9e5fee81fec2fd7 (diff)
downloadlibplist-35fdf8e73b9ee75b880cb9ff2de5491d7ddae20b.tar.gz
libplist-35fdf8e73b9ee75b880cb9ff2de5491d7ddae20b.tar.bz2
xplist: Prevent memory leaks when parsing fails
-rw-r--r--src/xplist.c57
1 files changed, 20 insertions, 37 deletions
diff --git a/src/xplist.c b/src/xplist.c
index 98d7375..19fbdbd 100644
--- a/src/xplist.c
+++ b/src/xplist.c
@@ -944,9 +944,8 @@ static void node_from_xml(parse_ctx ctx, plist_t *plist, uint32_t depth)
944 if (!tp) { 944 if (!tp) {
945 PLIST_XML_ERR("Could not parse text content for '%s' node\n", tag); 945 PLIST_XML_ERR("Could not parse text content for '%s' node\n", tag);
946 text_parts_free(first_part.next); 946 text_parts_free(first_part.next);
947 free(tag); 947 ctx->err++;
948 free(keyname); 948 goto err_out;
949 break;
950 } 949 }
951 if (tp->begin) { 950 if (tp->begin) {
952 int requires_free = 0; 951 int requires_free = 0;
@@ -955,9 +954,7 @@ static void node_from_xml(parse_ctx ctx, plist_t *plist, uint32_t depth)
955 PLIST_XML_ERR("Could not get text content for '%s' node\n", tag); 954 PLIST_XML_ERR("Could not get text content for '%s' node\n", tag);
956 text_parts_free(first_part.next); 955 text_parts_free(first_part.next);
957 ctx->err++; 956 ctx->err++;
958 free(tag); 957 goto err_out;
959 free(keyname);
960 break;
961 } 958 }
962 char *str = str_content; 959 char *str = str_content;
963 int is_negative = 0; 960 int is_negative = 0;
@@ -998,9 +995,8 @@ static void node_from_xml(parse_ctx ctx, plist_t *plist, uint32_t depth)
998 if (!tp) { 995 if (!tp) {
999 PLIST_XML_ERR("Could not parse text content for '%s' node\n", tag); 996 PLIST_XML_ERR("Could not parse text content for '%s' node\n", tag);
1000 text_parts_free(first_part.next); 997 text_parts_free(first_part.next);
1001 free(tag); 998 ctx->err++;
1002 free(keyname); 999 goto err_out;
1003 break;
1004 } 1000 }
1005 if (tp->begin) { 1001 if (tp->begin) {
1006 int requires_free = 0; 1002 int requires_free = 0;
@@ -1009,9 +1005,7 @@ static void node_from_xml(parse_ctx ctx, plist_t *plist, uint32_t depth)
1009 PLIST_XML_ERR("Could not get text content for '%s' node\n", tag); 1005 PLIST_XML_ERR("Could not get text content for '%s' node\n", tag);
1010 text_parts_free(first_part.next); 1006 text_parts_free(first_part.next);
1011 ctx->err++; 1007 ctx->err++;
1012 free(tag); 1008 goto err_out;
1013 free(keyname);
1014 break;
1015 } 1009 }
1016 data->realval = atof(str_content); 1010 data->realval = atof(str_content);
1017 if (requires_free) { 1011 if (requires_free) {
@@ -1045,18 +1039,15 @@ static void node_from_xml(parse_ctx ctx, plist_t *plist, uint32_t depth)
1045 if (!tp) { 1039 if (!tp) {
1046 PLIST_XML_ERR("Could not parse text content for '%s' node\n", tag); 1040 PLIST_XML_ERR("Could not parse text content for '%s' node\n", tag);
1047 text_parts_free(first_part.next); 1041 text_parts_free(first_part.next);
1048 free(tag); 1042 ctx->err++;
1049 free(keyname); 1043 goto err_out;
1050 break;
1051 } 1044 }
1052 str = text_parts_get_content(tp, 1, &length, NULL); 1045 str = text_parts_get_content(tp, 1, &length, NULL);
1053 text_parts_free(first_part.next); 1046 text_parts_free(first_part.next);
1054 if (!str) { 1047 if (!str) {
1055 PLIST_XML_ERR("Could not get text content for '%s' node\n", tag); 1048 PLIST_XML_ERR("Could not get text content for '%s' node\n", tag);
1056 ctx->err++; 1049 ctx->err++;
1057 free(tag); 1050 goto err_out;
1058 free(keyname);
1059 return;
1060 } 1051 }
1061 if (!strcmp(tag, "key") && !keyname && *plist && (plist_get_node_type(*plist) == PLIST_DICT)) { 1052 if (!strcmp(tag, "key") && !keyname && *plist && (plist_get_node_type(*plist) == PLIST_DICT)) {
1062 keyname = str; 1053 keyname = str;
@@ -1080,9 +1071,8 @@ static void node_from_xml(parse_ctx ctx, plist_t *plist, uint32_t depth)
1080 if (!tp) { 1071 if (!tp) {
1081 PLIST_XML_ERR("Could not parse text content for '%s' node\n", tag); 1072 PLIST_XML_ERR("Could not parse text content for '%s' node\n", tag);
1082 text_parts_free(first_part.next); 1073 text_parts_free(first_part.next);
1083 free(tag); 1074 ctx->err++;
1084 free(keyname); 1075 goto err_out;
1085 break;
1086 } 1076 }
1087 if (tp->begin) { 1077 if (tp->begin) {
1088 int requires_free = 0; 1078 int requires_free = 0;
@@ -1091,9 +1081,7 @@ static void node_from_xml(parse_ctx ctx, plist_t *plist, uint32_t depth)
1091 PLIST_XML_ERR("Could not get text content for '%s' node\n", tag); 1081 PLIST_XML_ERR("Could not get text content for '%s' node\n", tag);
1092 text_parts_free(first_part.next); 1082 text_parts_free(first_part.next);
1093 ctx->err++; 1083 ctx->err++;
1094 free(tag); 1084 goto err_out;
1095 free(keyname);
1096 break;
1097 } 1085 }
1098 size_t size = tp->length; 1086 size_t size = tp->length;
1099 data->buff = base64decode(str_content, &size); 1087 data->buff = base64decode(str_content, &size);
@@ -1113,9 +1101,8 @@ static void node_from_xml(parse_ctx ctx, plist_t *plist, uint32_t depth)
1113 if (!tp) { 1101 if (!tp) {
1114 PLIST_XML_ERR("Could not parse text content for '%s' node\n", tag); 1102 PLIST_XML_ERR("Could not parse text content for '%s' node\n", tag);
1115 text_parts_free(first_part.next); 1103 text_parts_free(first_part.next);
1116 free(tag); 1104 ctx->err++;
1117 free(keyname); 1105 goto err_out;
1118 break;
1119 } 1106 }
1120 Time64_T timev = 0; 1107 Time64_T timev = 0;
1121 if (tp->begin) { 1108 if (tp->begin) {
@@ -1126,9 +1113,7 @@ static void node_from_xml(parse_ctx ctx, plist_t *plist, uint32_t depth)
1126 PLIST_XML_ERR("Could not get text content for '%s' node\n", tag); 1113 PLIST_XML_ERR("Could not get text content for '%s' node\n", tag);
1127 text_parts_free(first_part.next); 1114 text_parts_free(first_part.next);
1128 ctx->err++; 1115 ctx->err++;
1129 free(tag); 1116 goto err_out;
1130 free(keyname);
1131 break;
1132 } 1117 }
1133 1118
1134 if ((length >= 11) && (length < 32)) { 1119 if ((length >= 11) && (length < 32)) {
@@ -1157,9 +1142,7 @@ static void node_from_xml(parse_ctx ctx, plist_t *plist, uint32_t depth)
1157 PLIST_XML_ERR("Unexpected tag <%s%s> encountered\n", tag, (is_empty) ? "/" : ""); 1142 PLIST_XML_ERR("Unexpected tag <%s%s> encountered\n", tag, (is_empty) ? "/" : "");
1158 ctx->pos = ctx->end; 1143 ctx->pos = ctx->end;
1159 ctx->err++; 1144 ctx->err++;
1160 free(tag); 1145 goto err_out;
1161 free(keyname);
1162 return;
1163 } 1146 }
1164 if (subnode && !closing_tag) { 1147 if (subnode && !closing_tag) {
1165 /* parse sub nodes for structured types */ 1148 /* parse sub nodes for structured types */
@@ -1169,9 +1152,7 @@ static void node_from_xml(parse_ctx ctx, plist_t *plist, uint32_t depth)
1169 node_from_xml(ctx, &subnode, depth+1); 1152 node_from_xml(ctx, &subnode, depth+1);
1170 if (ctx->err) { 1153 if (ctx->err) {
1171 /* make sure to bail out if parsing failed */ 1154 /* make sure to bail out if parsing failed */
1172 free(tag); 1155 goto err_out;
1173 free(keyname);
1174 return;
1175 } 1156 }
1176 if ((data->type == PLIST_DICT) && (plist_dict_get_size(subnode) == 1)) { 1157 if ((data->type == PLIST_DICT) && (plist_dict_get_size(subnode) == 1)) {
1177 /* convert XML CF$UID dictionaries to PLIST_UID nodes */ 1158 /* convert XML CF$UID dictionaries to PLIST_UID nodes */
@@ -1239,11 +1220,13 @@ static void node_from_xml(parse_ctx ctx, plist_t *plist, uint32_t depth)
1239 break; 1220 break;
1240 } 1221 }
1241 } 1222 }
1223err_out:
1242 free(tag); 1224 free(tag);
1243 free(keyname); 1225 free(keyname);
1244 keyname = NULL; 1226 keyname = NULL;
1245 plist_free(subnode); 1227 plist_free(subnode);
1246 if (closing_tag) { 1228 subnode = NULL;
1229 if (closing_tag || ctx->err) {
1247 break; 1230 break;
1248 } 1231 }
1249 } 1232 }