diff options
| author | 2021-12-22 03:17:26 +0100 | |
|---|---|---|
| committer | 2021-12-22 03:17:26 +0100 | |
| commit | 70f4a422e01910cdb783aac81f13c11223c3acbd (patch) | |
| tree | 1279c0edd8b84b91d6a9bc757ea5dc8232f4d78f /src | |
| parent | 810e1a5936867a9f2c9f07df3a33a9d02fc03466 (diff) | |
| download | libplist-70f4a422e01910cdb783aac81f13c11223c3acbd.tar.gz libplist-70f4a422e01910cdb783aac81f13c11223c3acbd.tar.bz2 | |
Add a return value to plist_to_* and plist_from_* functions
This way it can be easier determined why an import/export operation failed
instead of just having a NULL result.
Diffstat (limited to 'src')
| -rw-r--r-- | src/bplist.c | 60 | ||||
| -rw-r--r-- | src/plist.c | 18 | ||||
| -rw-r--r-- | src/xplist.c | 61 |
3 files changed, 101 insertions, 38 deletions
diff --git a/src/bplist.c b/src/bplist.c index a6e6ded..57ec151 100644 --- a/src/bplist.c +++ b/src/bplist.c | |||
| @@ -774,7 +774,7 @@ static plist_t parse_bin_node_at_index(struct bplist_data *bplist, uint32_t node | |||
| 774 | return plist; | 774 | return plist; |
| 775 | } | 775 | } |
| 776 | 776 | ||
| 777 | PLIST_API void plist_from_bin(const char *plist_bin, uint32_t length, plist_t * plist) | 777 | PLIST_API plist_err_t plist_from_bin(const char *plist_bin, uint32_t length, plist_t * plist) |
| 778 | { | 778 | { |
| 779 | bplist_trailer_t *trailer = NULL; | 779 | bplist_trailer_t *trailer = NULL; |
| 780 | uint8_t offset_size = 0; | 780 | uint8_t offset_size = 0; |
| @@ -786,20 +786,28 @@ PLIST_API void plist_from_bin(const char *plist_bin, uint32_t length, plist_t * | |||
| 786 | const char *start_data = NULL; | 786 | const char *start_data = NULL; |
| 787 | const char *end_data = NULL; | 787 | const char *end_data = NULL; |
| 788 | 788 | ||
| 789 | if (!plist) { | ||
| 790 | return PLIST_ERR_INVALID_ARG; | ||
| 791 | } | ||
| 792 | *plist = NULL; | ||
| 793 | if (!plist_bin || length == 0) { | ||
| 794 | return PLIST_ERR_INVALID_ARG; | ||
| 795 | } | ||
| 796 | |||
| 789 | //first check we have enough data | 797 | //first check we have enough data |
| 790 | if (!(length >= BPLIST_MAGIC_SIZE + BPLIST_VERSION_SIZE + sizeof(bplist_trailer_t))) { | 798 | if (!(length >= BPLIST_MAGIC_SIZE + BPLIST_VERSION_SIZE + sizeof(bplist_trailer_t))) { |
| 791 | PLIST_BIN_ERR("plist data is to small to hold a binary plist\n"); | 799 | PLIST_BIN_ERR("plist data is to small to hold a binary plist\n"); |
| 792 | return; | 800 | return PLIST_ERR_PARSE; |
| 793 | } | 801 | } |
| 794 | //check that plist_bin in actually a plist | 802 | //check that plist_bin in actually a plist |
| 795 | if (memcmp(plist_bin, BPLIST_MAGIC, BPLIST_MAGIC_SIZE) != 0) { | 803 | if (memcmp(plist_bin, BPLIST_MAGIC, BPLIST_MAGIC_SIZE) != 0) { |
| 796 | PLIST_BIN_ERR("bplist magic mismatch\n"); | 804 | PLIST_BIN_ERR("bplist magic mismatch\n"); |
| 797 | return; | 805 | return PLIST_ERR_PARSE; |
| 798 | } | 806 | } |
| 799 | //check for known version | 807 | //check for known version |
| 800 | if (memcmp(plist_bin + BPLIST_MAGIC_SIZE, BPLIST_VERSION, BPLIST_VERSION_SIZE) != 0) { | 808 | if (memcmp(plist_bin + BPLIST_MAGIC_SIZE, BPLIST_VERSION, BPLIST_VERSION_SIZE) != 0) { |
| 801 | PLIST_BIN_ERR("unsupported binary plist version '%.2s\n", plist_bin+BPLIST_MAGIC_SIZE); | 809 | PLIST_BIN_ERR("unsupported binary plist version '%.2s\n", plist_bin+BPLIST_MAGIC_SIZE); |
| 802 | return; | 810 | return PLIST_ERR_PARSE; |
| 803 | } | 811 | } |
| 804 | 812 | ||
| 805 | start_data = plist_bin + BPLIST_MAGIC_SIZE + BPLIST_VERSION_SIZE; | 813 | start_data = plist_bin + BPLIST_MAGIC_SIZE + BPLIST_VERSION_SIZE; |
| @@ -816,37 +824,37 @@ PLIST_API void plist_from_bin(const char *plist_bin, uint32_t length, plist_t * | |||
| 816 | 824 | ||
| 817 | if (num_objects == 0) { | 825 | if (num_objects == 0) { |
| 818 | PLIST_BIN_ERR("number of objects must be larger than 0\n"); | 826 | PLIST_BIN_ERR("number of objects must be larger than 0\n"); |
| 819 | return; | 827 | return PLIST_ERR_PARSE; |
| 820 | } | 828 | } |
| 821 | 829 | ||
| 822 | if (offset_size == 0) { | 830 | if (offset_size == 0) { |
| 823 | PLIST_BIN_ERR("offset size in trailer must be larger than 0\n"); | 831 | PLIST_BIN_ERR("offset size in trailer must be larger than 0\n"); |
| 824 | return; | 832 | return PLIST_ERR_PARSE; |
| 825 | } | 833 | } |
| 826 | 834 | ||
| 827 | if (ref_size == 0) { | 835 | if (ref_size == 0) { |
| 828 | PLIST_BIN_ERR("object reference size in trailer must be larger than 0\n"); | 836 | PLIST_BIN_ERR("object reference size in trailer must be larger than 0\n"); |
| 829 | return; | 837 | return PLIST_ERR_PARSE; |
| 830 | } | 838 | } |
| 831 | 839 | ||
| 832 | if (root_object >= num_objects) { | 840 | if (root_object >= num_objects) { |
| 833 | PLIST_BIN_ERR("root object index (%" PRIu64 ") must be smaller than number of objects (%" PRIu64 ")\n", root_object, num_objects); | 841 | PLIST_BIN_ERR("root object index (%" PRIu64 ") must be smaller than number of objects (%" PRIu64 ")\n", root_object, num_objects); |
| 834 | return; | 842 | return PLIST_ERR_PARSE; |
| 835 | } | 843 | } |
| 836 | 844 | ||
| 837 | if (offset_table < start_data || offset_table >= end_data) { | 845 | if (offset_table < start_data || offset_table >= end_data) { |
| 838 | PLIST_BIN_ERR("offset table offset points outside of valid range\n"); | 846 | PLIST_BIN_ERR("offset table offset points outside of valid range\n"); |
| 839 | return; | 847 | return PLIST_ERR_PARSE; |
| 840 | } | 848 | } |
| 841 | 849 | ||
| 842 | if (uint64_mul_overflow(num_objects, offset_size, &offset_table_size)) { | 850 | if (uint64_mul_overflow(num_objects, offset_size, &offset_table_size)) { |
| 843 | PLIST_BIN_ERR("integer overflow when calculating offset table size\n"); | 851 | PLIST_BIN_ERR("integer overflow when calculating offset table size\n"); |
| 844 | return; | 852 | return PLIST_ERR_PARSE; |
| 845 | } | 853 | } |
| 846 | 854 | ||
| 847 | if (offset_table_size > (uint64_t)(end_data - offset_table)) { | 855 | if (offset_table_size > (uint64_t)(end_data - offset_table)) { |
| 848 | PLIST_BIN_ERR("offset table points outside of valid range\n"); | 856 | PLIST_BIN_ERR("offset table points outside of valid range\n"); |
| 849 | return; | 857 | return PLIST_ERR_PARSE; |
| 850 | } | 858 | } |
| 851 | 859 | ||
| 852 | struct bplist_data bplist; | 860 | struct bplist_data bplist; |
| @@ -861,12 +869,18 @@ PLIST_API void plist_from_bin(const char *plist_bin, uint32_t length, plist_t * | |||
| 861 | 869 | ||
| 862 | if (!bplist.used_indexes) { | 870 | if (!bplist.used_indexes) { |
| 863 | PLIST_BIN_ERR("failed to create array to hold used node indexes. Out of memory?\n"); | 871 | PLIST_BIN_ERR("failed to create array to hold used node indexes. Out of memory?\n"); |
| 864 | return; | 872 | return PLIST_ERR_NO_MEM; |
| 865 | } | 873 | } |
| 866 | 874 | ||
| 867 | *plist = parse_bin_node_at_index(&bplist, root_object); | 875 | *plist = parse_bin_node_at_index(&bplist, root_object); |
| 868 | 876 | ||
| 869 | ptr_array_free(bplist.used_indexes); | 877 | ptr_array_free(bplist.used_indexes); |
| 878 | |||
| 879 | if (!*plist) { | ||
| 880 | return PLIST_ERR_PARSE; | ||
| 881 | } | ||
| 882 | |||
| 883 | return PLIST_ERR_SUCCESS; | ||
| 870 | } | 884 | } |
| 871 | 885 | ||
| 872 | static unsigned int plist_data_hash(const void* key) | 886 | static unsigned int plist_data_hash(const void* key) |
| @@ -1163,7 +1177,7 @@ static int is_ascii_string(char* s, int len) | |||
| 1163 | return ret; | 1177 | return ret; |
| 1164 | } | 1178 | } |
| 1165 | 1179 | ||
| 1166 | PLIST_API void plist_to_bin(plist_t plist, char **plist_bin, uint32_t * length) | 1180 | PLIST_API plist_err_t plist_to_bin(plist_t plist, char **plist_bin, uint32_t * length) |
| 1167 | { | 1181 | { |
| 1168 | ptrarray_t* objects = NULL; | 1182 | ptrarray_t* objects = NULL; |
| 1169 | hashtable_t* ref_table = NULL; | 1183 | hashtable_t* ref_table = NULL; |
| @@ -1181,13 +1195,21 @@ PLIST_API void plist_to_bin(plist_t plist, char **plist_bin, uint32_t * length) | |||
| 1181 | uint64_t objects_len = 0; | 1195 | uint64_t objects_len = 0; |
| 1182 | 1196 | ||
| 1183 | //check for valid input | 1197 | //check for valid input |
| 1184 | if (!plist || !plist_bin || *plist_bin || !length) | 1198 | if (!plist || !plist_bin || !length) { |
| 1185 | return; | 1199 | return PLIST_ERR_INVALID_ARG; |
| 1200 | } | ||
| 1186 | 1201 | ||
| 1187 | //list of objects | 1202 | //list of objects |
| 1188 | objects = ptr_array_new(4096); | 1203 | objects = ptr_array_new(4096); |
| 1204 | if (!objects) { | ||
| 1205 | return PLIST_ERR_NO_MEM; | ||
| 1206 | } | ||
| 1189 | //hashtable to write only once same nodes | 1207 | //hashtable to write only once same nodes |
| 1190 | ref_table = hash_table_new(plist_data_hash, plist_data_compare, free); | 1208 | ref_table = hash_table_new(plist_data_hash, plist_data_compare, free); |
| 1209 | if (!ref_table) { | ||
| 1210 | ptr_array_free(objects); | ||
| 1211 | return PLIST_ERR_NO_MEM; | ||
| 1212 | } | ||
| 1191 | 1213 | ||
| 1192 | //serialize plist | 1214 | //serialize plist |
| 1193 | ser_s.objects = objects; | 1215 | ser_s.objects = objects; |
| @@ -1212,6 +1234,7 @@ PLIST_API void plist_to_bin(plist_t plist, char **plist_bin, uint32_t * length) | |||
| 1212 | uint8_t bsize; | 1234 | uint8_t bsize; |
| 1213 | switch (data->type) | 1235 | switch (data->type) |
| 1214 | { | 1236 | { |
| 1237 | case PLIST_NULL: | ||
| 1215 | case PLIST_BOOLEAN: | 1238 | case PLIST_BOOLEAN: |
| 1216 | req += 1; | 1239 | req += 1; |
| 1217 | break; | 1240 | break; |
| @@ -1286,6 +1309,11 @@ PLIST_API void plist_to_bin(plist_t plist, char **plist_bin, uint32_t * length) | |||
| 1286 | 1309 | ||
| 1287 | //setup a dynamic bytes array to store bplist in | 1310 | //setup a dynamic bytes array to store bplist in |
| 1288 | bplist_buff = byte_array_new(req); | 1311 | bplist_buff = byte_array_new(req); |
| 1312 | if (!bplist_buff) { | ||
| 1313 | ptr_array_free(objects); | ||
| 1314 | hash_table_destroy(ref_table); | ||
| 1315 | return PLIST_ERR_NO_MEM; | ||
| 1316 | } | ||
| 1289 | 1317 | ||
| 1290 | //set magic number and version | 1318 | //set magic number and version |
| 1291 | byte_array_append(bplist_buff, BPLIST_MAGIC, BPLIST_MAGIC_SIZE); | 1319 | byte_array_append(bplist_buff, BPLIST_MAGIC, BPLIST_MAGIC_SIZE); |
| @@ -1385,4 +1413,6 @@ PLIST_API void plist_to_bin(plist_t plist, char **plist_bin, uint32_t * length) | |||
| 1385 | 1413 | ||
| 1386 | bplist_buff->data = NULL; // make sure we don't free the output buffer | 1414 | bplist_buff->data = NULL; // make sure we don't free the output buffer |
| 1387 | byte_array_free(bplist_buff); | 1415 | byte_array_free(bplist_buff); |
| 1416 | |||
| 1417 | return PLIST_ERR_SUCCESS; | ||
| 1388 | } | 1418 | } |
diff --git a/src/plist.c b/src/plist.c index 5453176..61b2913 100644 --- a/src/plist.c +++ b/src/plist.c | |||
| @@ -183,18 +183,22 @@ PLIST_API int plist_is_binary(const char *plist_data, uint32_t length) | |||
| 183 | } | 183 | } |
| 184 | 184 | ||
| 185 | 185 | ||
| 186 | PLIST_API void plist_from_memory(const char *plist_data, uint32_t length, plist_t * plist) | 186 | PLIST_API plist_err_t plist_from_memory(const char *plist_data, uint32_t length, plist_t * plist) |
| 187 | { | 187 | { |
| 188 | if (length < 8) { | 188 | int res = -1; |
| 189 | *plist = NULL; | 189 | if (!plist) { |
| 190 | return; | 190 | return PLIST_ERR_INVALID_ARG; |
| 191 | } | ||
| 192 | *plist = NULL; | ||
| 193 | if (!plist_data || length < 8) { | ||
| 194 | return PLIST_ERR_INVALID_ARG; | ||
| 191 | } | 195 | } |
| 192 | |||
| 193 | if (plist_is_binary(plist_data, length)) { | 196 | if (plist_is_binary(plist_data, length)) { |
| 194 | plist_from_bin(plist_data, length, plist); | 197 | res = plist_from_bin(plist_data, length, plist); |
| 195 | } else { | 198 | } else { |
| 196 | plist_from_xml(plist_data, length, plist); | 199 | res = plist_from_xml(plist_data, length, plist); |
| 197 | } | 200 | } |
| 201 | return res; | ||
| 198 | } | 202 | } |
| 199 | 203 | ||
| 200 | plist_t plist_new_node(plist_data_t data) | 204 | plist_t plist_new_node(plist_data_t data) |
diff --git a/src/xplist.c b/src/xplist.c index 94006f1..3971622 100644 --- a/src/xplist.c +++ b/src/xplist.c | |||
| @@ -143,7 +143,7 @@ static int node_to_xml(node_t* node, bytearray_t **outbuf, uint32_t depth) | |||
| 143 | 143 | ||
| 144 | if (!node) { | 144 | if (!node) { |
| 145 | PLIST_XML_WRITE_ERR("Encountered invalid empty node in property list\n"); | 145 | PLIST_XML_WRITE_ERR("Encountered invalid empty node in property list\n"); |
| 146 | return -1; | 146 | return PLIST_ERR_INVALID_ARG; |
| 147 | } | 147 | } |
| 148 | 148 | ||
| 149 | node_data = plist_get_data(node); | 149 | node_data = plist_get_data(node); |
| @@ -238,9 +238,9 @@ static int node_to_xml(node_t* node, bytearray_t **outbuf, uint32_t depth) | |||
| 238 | break; | 238 | break; |
| 239 | case PLIST_NULL: | 239 | case PLIST_NULL: |
| 240 | PLIST_XML_WRITE_ERR("PLIST_NULL type is not valid for XML format\n"); | 240 | PLIST_XML_WRITE_ERR("PLIST_NULL type is not valid for XML format\n"); |
| 241 | return -1; | 241 | return PLIST_ERR_FORMAT; |
| 242 | default: | 242 | default: |
| 243 | break; | 243 | return PLIST_ERR_UNKNOWN; |
| 244 | } | 244 | } |
| 245 | 245 | ||
| 246 | for (i = 0; i < depth; i++) { | 246 | for (i = 0; i < depth; i++) { |
| @@ -377,7 +377,7 @@ static int node_to_xml(node_t* node, bytearray_t **outbuf, uint32_t depth) | |||
| 377 | str_buf_append(*outbuf, ">", 1); | 377 | str_buf_append(*outbuf, ">", 1); |
| 378 | } | 378 | } |
| 379 | str_buf_append(*outbuf, "\n", 1); | 379 | str_buf_append(*outbuf, "\n", 1); |
| 380 | return 0; | 380 | return PLIST_ERR_SUCCESS; |
| 381 | } | 381 | } |
| 382 | 382 | ||
| 383 | static void parse_date(const char *strval, struct TM *btime) | 383 | static void parse_date(const char *strval, struct TM *btime) |
| @@ -438,11 +438,11 @@ static int num_digits_u(uint64_t i) | |||
| 438 | return n; | 438 | return n; |
| 439 | } | 439 | } |
| 440 | 440 | ||
| 441 | static void node_estimate_size(node_t *node, uint64_t *size, uint32_t depth) | 441 | static int node_estimate_size(node_t *node, uint64_t *size, uint32_t depth) |
| 442 | { | 442 | { |
| 443 | plist_data_t data; | 443 | plist_data_t data; |
| 444 | if (!node) { | 444 | if (!node) { |
| 445 | return; | 445 | return PLIST_ERR_INVALID_ARG; |
| 446 | } | 446 | } |
| 447 | data = plist_get_data(node); | 447 | data = plist_get_data(node); |
| 448 | if (node->children) { | 448 | if (node->children) { |
| @@ -511,28 +511,47 @@ static void node_estimate_size(node_t *node, uint64_t *size, uint32_t depth) | |||
| 511 | *size += 18; /* <key>CF$UID</key> */ | 511 | *size += 18; /* <key>CF$UID</key> */ |
| 512 | *size += (XPLIST_INT_LEN << 1) + 6; | 512 | *size += (XPLIST_INT_LEN << 1) + 6; |
| 513 | break; | 513 | break; |
| 514 | case PLIST_NULL: | ||
| 515 | PLIST_XML_WRITE_ERR("PLIST_NULL type is not valid for XML format\n"); | ||
| 516 | return PLIST_ERR_FORMAT; | ||
| 514 | default: | 517 | default: |
| 515 | break; | 518 | PLIST_XML_WRITE_ERR("invalid node type encountered\n"); |
| 519 | return PLIST_ERR_UNKNOWN; | ||
| 516 | } | 520 | } |
| 517 | *size += indent; | 521 | *size += indent; |
| 518 | } | 522 | } |
| 523 | return PLIST_ERR_SUCCESS; | ||
| 519 | } | 524 | } |
| 520 | 525 | ||
| 521 | PLIST_API void plist_to_xml(plist_t plist, char **plist_xml, uint32_t * length) | 526 | PLIST_API plist_err_t plist_to_xml(plist_t plist, char **plist_xml, uint32_t * length) |
| 522 | { | 527 | { |
| 523 | uint64_t size = 0; | 528 | uint64_t size = 0; |
| 524 | node_estimate_size(plist, &size, 0); | 529 | int res; |
| 530 | |||
| 531 | if (!plist || !plist_xml || !length) { | ||
| 532 | return PLIST_ERR_INVALID_ARG; | ||
| 533 | } | ||
| 534 | |||
| 535 | res = node_estimate_size(plist, &size, 0); | ||
| 536 | if (res < 0) { | ||
| 537 | return res; | ||
| 538 | } | ||
| 525 | size += sizeof(XML_PLIST_PROLOG) + sizeof(XML_PLIST_EPILOG) - 1; | 539 | size += sizeof(XML_PLIST_PROLOG) + sizeof(XML_PLIST_EPILOG) - 1; |
| 526 | 540 | ||
| 527 | strbuf_t *outbuf = str_buf_new(size); | 541 | strbuf_t *outbuf = str_buf_new(size); |
| 542 | if (!outbuf) { | ||
| 543 | PLIST_XML_WRITE_ERR("Could not allocate output buffer"); | ||
| 544 | return PLIST_ERR_NO_MEM; | ||
| 545 | } | ||
| 528 | 546 | ||
| 529 | str_buf_append(outbuf, XML_PLIST_PROLOG, sizeof(XML_PLIST_PROLOG)-1); | 547 | str_buf_append(outbuf, XML_PLIST_PROLOG, sizeof(XML_PLIST_PROLOG)-1); |
| 530 | 548 | ||
| 531 | if (node_to_xml(plist, &outbuf, 0) < 0) { | 549 | res = node_to_xml(plist, &outbuf, 0); |
| 550 | if (res < 0) { | ||
| 532 | str_buf_free(outbuf); | 551 | str_buf_free(outbuf); |
| 533 | *plist_xml = NULL; | 552 | *plist_xml = NULL; |
| 534 | *length = 0; | 553 | *length = 0; |
| 535 | return; | 554 | return res; |
| 536 | } | 555 | } |
| 537 | 556 | ||
| 538 | str_buf_append(outbuf, XML_PLIST_EPILOG, sizeof(XML_PLIST_EPILOG)); | 557 | str_buf_append(outbuf, XML_PLIST_EPILOG, sizeof(XML_PLIST_EPILOG)); |
| @@ -542,6 +561,8 @@ PLIST_API void plist_to_xml(plist_t plist, char **plist_xml, uint32_t * length) | |||
| 542 | 561 | ||
| 543 | outbuf->data = NULL; | 562 | outbuf->data = NULL; |
| 544 | str_buf_free(outbuf); | 563 | str_buf_free(outbuf); |
| 564 | |||
| 565 | return PLIST_ERR_SUCCESS; | ||
| 545 | } | 566 | } |
| 546 | 567 | ||
| 547 | struct _parse_ctx { | 568 | struct _parse_ctx { |
| @@ -932,8 +953,9 @@ static char* text_parts_get_content(text_part_t *tp, int unesc_entities, size_t | |||
| 932 | return str; | 953 | return str; |
| 933 | } | 954 | } |
| 934 | 955 | ||
| 935 | static void node_from_xml(parse_ctx ctx, plist_t *plist) | 956 | static int node_from_xml(parse_ctx ctx, plist_t *plist) |
| 936 | { | 957 | { |
| 958 | int res; | ||
| 937 | char *tag = NULL; | 959 | char *tag = NULL; |
| 938 | char *keyname = NULL; | 960 | char *keyname = NULL; |
| 939 | plist_t subnode = NULL; | 961 | plist_t subnode = NULL; |
| @@ -1427,17 +1449,24 @@ err_out: | |||
| 1427 | if (ctx->err) { | 1449 | if (ctx->err) { |
| 1428 | plist_free(*plist); | 1450 | plist_free(*plist); |
| 1429 | *plist = NULL; | 1451 | *plist = NULL; |
| 1452 | res = PLIST_ERR_PARSE; | ||
| 1453 | } else { | ||
| 1454 | res = PLIST_ERR_SUCCESS; | ||
| 1430 | } | 1455 | } |
| 1456 | return res; | ||
| 1431 | } | 1457 | } |
| 1432 | 1458 | ||
| 1433 | PLIST_API void plist_from_xml(const char *plist_xml, uint32_t length, plist_t * plist) | 1459 | PLIST_API plist_err_t plist_from_xml(const char *plist_xml, uint32_t length, plist_t * plist) |
| 1434 | { | 1460 | { |
| 1461 | if (!plist) { | ||
| 1462 | return PLIST_ERR_INVALID_ARG; | ||
| 1463 | } | ||
| 1464 | *plist = NULL; | ||
| 1435 | if (!plist_xml || (length == 0)) { | 1465 | if (!plist_xml || (length == 0)) { |
| 1436 | *plist = NULL; | 1466 | return PLIST_ERR_INVALID_ARG; |
| 1437 | return; | ||
| 1438 | } | 1467 | } |
| 1439 | 1468 | ||
| 1440 | struct _parse_ctx ctx = { plist_xml, plist_xml + length, 0 }; | 1469 | struct _parse_ctx ctx = { plist_xml, plist_xml + length, 0 }; |
| 1441 | 1470 | ||
| 1442 | node_from_xml(&ctx, plist); | 1471 | return node_from_xml(&ctx, plist); |
| 1443 | } | 1472 | } |
