diff options
| author | 2017-02-06 20:02:39 +0100 | |
|---|---|---|
| committer | 2017-02-06 20:02:39 +0100 | |
| commit | 35fdf8e73b9ee75b880cb9ff2de5491d7ddae20b (patch) | |
| tree | 3209a50fdf1b2a53ffd4c0d93ebf81018dfaee2b /src/xplist.c | |
| parent | c98451f9eabb68df3dfabaedc9e5fee81fec2fd7 (diff) | |
| download | libplist-35fdf8e73b9ee75b880cb9ff2de5491d7ddae20b.tar.gz libplist-35fdf8e73b9ee75b880cb9ff2de5491d7ddae20b.tar.bz2 | |
xplist: Prevent memory leaks when parsing fails
Diffstat (limited to 'src/xplist.c')
| -rw-r--r-- | src/xplist.c | 57 |
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 | } |
| 1223 | err_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 | } |
