summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Nikias Bassen2026-01-26 18:56:41 +0100
committerGravatar Nikias Bassen2026-01-26 18:56:41 +0100
commitebf24567ea5e4f72bd5acbc22f085e9d0b208e05 (patch)
tree1eedfa999d8a53c96f53ad713fd33e41698c156b
parent57664f6394d9f96ffd54a8bb71fafb6d01528300 (diff)
downloadlibplist-ebf24567ea5e4f72bd5acbc22f085e9d0b208e05.tar.gz
libplist-ebf24567ea5e4f72bd5acbc22f085e9d0b208e05.tar.bz2
xplist: Use small stack buffer instead of dynamic allocations
This removes the necessity for malloc failures and reduces overhead
-rw-r--r--src/xplist.c47
1 files changed, 16 insertions, 31 deletions
diff --git a/src/xplist.c b/src/xplist.c
index 32e3f8b..2c21272 100644
--- a/src/xplist.c
+++ b/src/xplist.c
@@ -143,7 +143,7 @@ static plist_err_t node_to_xml(node_t node, bytearray_t **outbuf, uint32_t depth
143 143
144 const char *tag = NULL; 144 const char *tag = NULL;
145 size_t tag_len = 0; 145 size_t tag_len = 0;
146 char *val = NULL; 146 char val[64] = { 0 };
147 size_t val_len = 0; 147 size_t val_len = 0;
148 148
149 uint32_t i = 0; 149 uint32_t i = 0;
@@ -172,19 +172,17 @@ static plist_err_t node_to_xml(node_t node, bytearray_t **outbuf, uint32_t depth
172 case PLIST_INT: 172 case PLIST_INT:
173 tag = XPLIST_INT; 173 tag = XPLIST_INT;
174 tag_len = XPLIST_INT_LEN; 174 tag_len = XPLIST_INT_LEN;
175 val = (char*)malloc(64);
176 if (node_data->length == 16) { 175 if (node_data->length == 16) {
177 val_len = snprintf(val, 64, "%" PRIu64, node_data->intval); 176 val_len = snprintf(val, sizeof(val), "%" PRIu64, node_data->intval);
178 } else { 177 } else {
179 val_len = snprintf(val, 64, "%" PRIi64, node_data->intval); 178 val_len = snprintf(val, sizeof(val), "%" PRIi64, node_data->intval);
180 } 179 }
181 break; 180 break;
182 181
183 case PLIST_REAL: 182 case PLIST_REAL:
184 tag = XPLIST_REAL; 183 tag = XPLIST_REAL;
185 tag_len = XPLIST_REAL_LEN; 184 tag_len = XPLIST_REAL_LEN;
186 val = (char*)malloc(64); 185 val_len = dtostr(val, sizeof(val), node_data->realval);
187 val_len = dtostr(val, 64, node_data->realval);
188 break; 186 break;
189 187
190 case PLIST_STRING: 188 case PLIST_STRING:
@@ -222,13 +220,11 @@ static plist_err_t node_to_xml(node_t node, bytearray_t **outbuf, uint32_t depth
222 struct TM _btime; 220 struct TM _btime;
223 struct TM *btime = gmtime64_r(&timev, &_btime); 221 struct TM *btime = gmtime64_r(&timev, &_btime);
224 if (btime) { 222 if (btime) {
225 val = (char*)calloc(1, 24);
226 struct tm _tmcopy; 223 struct tm _tmcopy;
227 copy_TM64_to_tm(btime, &_tmcopy); 224 copy_TM64_to_tm(btime, &_tmcopy);
228 val_len = strftime(val, 24, "%Y-%m-%dT%H:%M:%SZ", &_tmcopy); 225 val_len = strftime(val, sizeof(val), "%Y-%m-%dT%H:%M:%SZ", &_tmcopy);
229 if (val_len <= 0) { 226 if (val_len <= 0) {
230 free (val); 227 snprintf(val, sizeof(val), "1970-01-01T00:00:00Z");
231 val = NULL;
232 } 228 }
233 } 229 }
234 } 230 }
@@ -236,11 +232,10 @@ static plist_err_t node_to_xml(node_t node, bytearray_t **outbuf, uint32_t depth
236 case PLIST_UID: 232 case PLIST_UID:
237 tag = XPLIST_DICT; 233 tag = XPLIST_DICT;
238 tag_len = XPLIST_DICT_LEN; 234 tag_len = XPLIST_DICT_LEN;
239 val = (char*)malloc(64);
240 if (node_data->length == 16) { 235 if (node_data->length == 16) {
241 val_len = snprintf(val, 64, "%" PRIu64, node_data->intval); 236 val_len = snprintf(val, sizeof(val), "%" PRIu64, node_data->intval);
242 } else { 237 } else {
243 val_len = snprintf(val, 64, "%" PRIi64, node_data->intval); 238 val_len = snprintf(val, sizeof(val), "%" PRIi64, node_data->intval);
244 } 239 }
245 break; 240 break;
246 case PLIST_NULL: 241 case PLIST_NULL:
@@ -344,7 +339,7 @@ static plist_err_t node_to_xml(node_t node, bytearray_t **outbuf, uint32_t depth
344 for (i = 0; i < depth; i++) { 339 for (i = 0; i < depth; i++) {
345 str_buf_append(*outbuf, "\t", 1); 340 str_buf_append(*outbuf, "\t", 1);
346 } 341 }
347 } else if (val) { 342 } else if (val_len > 0) {
348 str_buf_append(*outbuf, ">", 1); 343 str_buf_append(*outbuf, ">", 1);
349 tagOpen = TRUE; 344 tagOpen = TRUE;
350 str_buf_append(*outbuf, val, val_len); 345 str_buf_append(*outbuf, val, val_len);
@@ -355,7 +350,6 @@ static plist_err_t node_to_xml(node_t node, bytearray_t **outbuf, uint32_t depth
355 tagOpen = FALSE; 350 tagOpen = FALSE;
356 str_buf_append(*outbuf, "/>", 2); 351 str_buf_append(*outbuf, "/>", 2);
357 } 352 }
358 free(val);
359 353
360 if (isStruct) { 354 if (isStruct) {
361 /* add newline for structured types */ 355 /* add newline for structured types */
@@ -1002,7 +996,7 @@ static char* text_parts_get_content(text_part_t *tp, int unesc_entities, size_t
1002 996
1003static plist_err_t node_from_xml(parse_ctx ctx, plist_t *plist) 997static plist_err_t node_from_xml(parse_ctx ctx, plist_t *plist)
1004{ 998{
1005 char *tag = NULL; 999 char tag[16] = { 0 };
1006 char *keyname = NULL; 1000 char *keyname = NULL;
1007 plist_t subnode = NULL; 1001 plist_t subnode = NULL;
1008 const char *p = NULL; 1002 const char *p = NULL;
@@ -1109,7 +1103,12 @@ static plist_err_t node_from_xml(parse_ctx ctx, plist_t *plist)
1109 goto err_out; 1103 goto err_out;
1110 } 1104 }
1111 size_t taglen = ctx->pos - p; 1105 size_t taglen = ctx->pos - p;
1112 tag = (char*)malloc(taglen + 1); 1106 if (taglen >= sizeof(tag)) {
1107 PLIST_XML_ERR("Unexpected tag <%.*s> encountered\n", (int)taglen, p);
1108 ctx->pos = ctx->end;
1109 ctx->err = PLIST_ERR_PARSE;
1110 goto err_out;
1111 }
1113 memcpy(tag, p, taglen); 1112 memcpy(tag, p, taglen);
1114 tag[taglen] = '\0'; 1113 tag[taglen] = '\0';
1115 if (*ctx->pos != '>') { 1114 if (*ctx->pos != '>') {
@@ -1133,8 +1132,6 @@ static plist_err_t node_from_xml(parse_ctx ctx, plist_t *plist)
1133 } 1132 }
1134 ctx->pos++; 1133 ctx->pos++;
1135 if (!strcmp(tag, "plist")) { 1134 if (!strcmp(tag, "plist")) {
1136 free(tag);
1137 tag = NULL;
1138 has_content = 0; 1135 has_content = 0;
1139 1136
1140 if (!node_path && *plist) { 1137 if (!node_path && *plist) {
@@ -1177,10 +1174,6 @@ static plist_err_t node_from_xml(parse_ctx ctx, plist_t *plist)
1177 struct node_path_item *path_item = node_path; 1174 struct node_path_item *path_item = node_path;
1178 node_path = (struct node_path_item*)node_path->prev; 1175 node_path = (struct node_path_item*)node_path->prev;
1179 free(path_item); 1176 free(path_item);
1180
1181 free(tag);
1182 tag = NULL;
1183
1184 continue; 1177 continue;
1185 } 1178 }
1186 1179
@@ -1306,8 +1299,6 @@ static plist_err_t node_from_xml(parse_ctx ctx, plist_t *plist)
1306 } 1299 }
1307 if (!strcmp(tag, "key") && !keyname && parent && (plist_get_node_type(parent) == PLIST_DICT)) { 1300 if (!strcmp(tag, "key") && !keyname && parent && (plist_get_node_type(parent) == PLIST_DICT)) {
1308 keyname = str; 1301 keyname = str;
1309 free(tag);
1310 tag = NULL;
1311 plist_free(subnode); 1302 plist_free(subnode);
1312 subnode = NULL; 1303 subnode = NULL;
1313 continue; 1304 continue;
@@ -1318,8 +1309,6 @@ static plist_err_t node_from_xml(parse_ctx ctx, plist_t *plist)
1318 } else { 1309 } else {
1319 if (!strcmp(tag, "key") && !keyname && parent && (plist_get_node_type(parent) == PLIST_DICT)) { 1310 if (!strcmp(tag, "key") && !keyname && parent && (plist_get_node_type(parent) == PLIST_DICT)) {
1320 keyname = strdup(""); 1311 keyname = strdup("");
1321 free(tag);
1322 tag = NULL;
1323 plist_free(subnode); 1312 plist_free(subnode);
1324 subnode = NULL; 1313 subnode = NULL;
1325 continue; 1314 continue;
@@ -1481,9 +1470,6 @@ static plist_err_t node_from_xml(parse_ctx ctx, plist_t *plist)
1481 goto err_out; 1470 goto err_out;
1482 } 1471 }
1483 } 1472 }
1484
1485 free(tag);
1486 tag = NULL;
1487 free(keyname); 1473 free(keyname);
1488 keyname = NULL; 1474 keyname = NULL;
1489 plist_free(subnode); 1475 plist_free(subnode);
@@ -1497,7 +1483,6 @@ static plist_err_t node_from_xml(parse_ctx ctx, plist_t *plist)
1497 } 1483 }
1498 1484
1499err_out: 1485err_out:
1500 free(tag);
1501 free(keyname); 1486 free(keyname);
1502 plist_free(subnode); 1487 plist_free(subnode);
1503 1488