summaryrefslogtreecommitdiffstats
path: root/src/bplist.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/bplist.c')
-rw-r--r--src/bplist.c26
1 files changed, 22 insertions, 4 deletions
diff --git a/src/bplist.c b/src/bplist.c
index a2dc957..254c0ff 100644
--- a/src/bplist.c
+++ b/src/bplist.c
@@ -239,6 +239,7 @@ struct bplist_data {
239 const char* offset_table; 239 const char* offset_table;
240 uint32_t level; 240 uint32_t level;
241 ptrarray_t* used_indexes; 241 ptrarray_t* used_indexes;
242 plist_err_t err;
242}; 243};
243 244
244#ifdef DEBUG 245#ifdef DEBUG
@@ -787,6 +788,7 @@ static plist_t parse_bin_node_at_index(struct bplist_data *bplist, uint32_t node
787 788
788 if (node_index >= bplist->num_objects) { 789 if (node_index >= bplist->num_objects) {
789 PLIST_BIN_ERR("node index (%u) must be smaller than the number of objects (%" PRIu64 ")\n", node_index, bplist->num_objects); 790 PLIST_BIN_ERR("node index (%u) must be smaller than the number of objects (%" PRIu64 ")\n", node_index, bplist->num_objects);
791 bplist->err = PLIST_ERR_PARSE;
790 return NULL; 792 return NULL;
791 } 793 }
792 794
@@ -794,6 +796,7 @@ static plist_t parse_bin_node_at_index(struct bplist_data *bplist, uint32_t node
794 if (idx_ptr < bplist->offset_table || 796 if (idx_ptr < bplist->offset_table ||
795 idx_ptr >= bplist->offset_table + bplist->num_objects * bplist->offset_size) { 797 idx_ptr >= bplist->offset_table + bplist->num_objects * bplist->offset_size) {
796 PLIST_BIN_ERR("node index %u points outside of valid range\n", node_index); 798 PLIST_BIN_ERR("node index %u points outside of valid range\n", node_index);
799 bplist->err = PLIST_ERR_PARSE;
797 return NULL; 800 return NULL;
798 } 801 }
799 802
@@ -801,6 +804,14 @@ static plist_t parse_bin_node_at_index(struct bplist_data *bplist, uint32_t node
801 /* make sure the node offset is in a sane range */ 804 /* make sure the node offset is in a sane range */
802 if ((ptr < bplist->data+BPLIST_MAGIC_SIZE+BPLIST_VERSION_SIZE) || (ptr >= bplist->offset_table)) { 805 if ((ptr < bplist->data+BPLIST_MAGIC_SIZE+BPLIST_VERSION_SIZE) || (ptr >= bplist->offset_table)) {
803 PLIST_BIN_ERR("offset for node index %u points outside of valid range\n", node_index); 806 PLIST_BIN_ERR("offset for node index %u points outside of valid range\n", node_index);
807 bplist->err = PLIST_ERR_PARSE;
808 return NULL;
809 }
810
811 /* check nesting depth */
812 if (bplist->level > PLIST_MAX_NESTING_DEPTH) {
813 PLIST_BIN_ERR("maximum nesting depth (%u) exceeded\n",(unsigned)PLIST_MAX_NESTING_DEPTH);
814 bplist->err = PLIST_ERR_MAX_NESTING;
804 return NULL; 815 return NULL;
805 } 816 }
806 817
@@ -820,6 +831,7 @@ static plist_t parse_bin_node_at_index(struct bplist_data *bplist, uint32_t node
820 void *node_level = ptr_array_index(bplist->used_indexes, bplist->level); 831 void *node_level = ptr_array_index(bplist->used_indexes, bplist->level);
821 if (node_i == node_level) { 832 if (node_i == node_level) {
822 PLIST_BIN_ERR("recursion detected in binary plist\n"); 833 PLIST_BIN_ERR("recursion detected in binary plist\n");
834 bplist->err = PLIST_ERR_PARSE;
823 return NULL; 835 return NULL;
824 } 836 }
825 } 837 }
@@ -931,6 +943,7 @@ plist_err_t plist_from_bin(const char *plist_bin, uint32_t length, plist_t * pli
931 bplist.offset_table = offset_table; 943 bplist.offset_table = offset_table;
932 bplist.level = 0; 944 bplist.level = 0;
933 bplist.used_indexes = ptr_array_new(16); 945 bplist.used_indexes = ptr_array_new(16);
946 bplist.err = PLIST_ERR_SUCCESS;
934 947
935 if (!bplist.used_indexes) { 948 if (!bplist.used_indexes) {
936 PLIST_BIN_ERR("failed to create array to hold used node indexes. Out of memory?\n"); 949 PLIST_BIN_ERR("failed to create array to hold used node indexes. Out of memory?\n");
@@ -942,7 +955,7 @@ plist_err_t plist_from_bin(const char *plist_bin, uint32_t length, plist_t * pli
942 ptr_array_free(bplist.used_indexes); 955 ptr_array_free(bplist.used_indexes);
943 956
944 if (!*plist) { 957 if (!*plist) {
945 return PLIST_ERR_PARSE; 958 return (bplist.err != PLIST_ERR_SUCCESS) ? bplist.err : PLIST_ERR_PARSE;
946 } 959 }
947 960
948 return PLIST_ERR_SUCCESS; 961 return PLIST_ERR_SUCCESS;
@@ -1002,11 +1015,16 @@ struct serialize_s
1002 hashtable_t* in_stack; 1015 hashtable_t* in_stack;
1003}; 1016};
1004 1017
1005static plist_err_t serialize_plist(node_t node, void* data) 1018static plist_err_t serialize_plist(node_t node, void* data, uint32_t depth)
1006{ 1019{
1007 uint64_t *index_val = NULL; 1020 uint64_t *index_val = NULL;
1008 struct serialize_s *ser = (struct serialize_s *) data; 1021 struct serialize_s *ser = (struct serialize_s *) data;
1009 1022
1023 if (depth > PLIST_MAX_NESTING_DEPTH) {
1024 PLIST_BIN_WRITE_ERR("maximum nesting depth (%u) exceeded\n", (unsigned)PLIST_MAX_NESTING_DEPTH);
1025 return PLIST_ERR_MAX_NESTING;
1026 }
1027
1010 // circular reference check: is node on current recursion stack? 1028 // circular reference check: is node on current recursion stack?
1011 if (hash_table_lookup(ser->in_stack, node)) { 1029 if (hash_table_lookup(ser->in_stack, node)) {
1012 PLIST_BIN_WRITE_ERR("circular reference detected\n"); 1030 PLIST_BIN_WRITE_ERR("circular reference detected\n");
@@ -1036,7 +1054,7 @@ static plist_err_t serialize_plist(node_t node, void* data)
1036 node_t ch; 1054 node_t ch;
1037 plist_err_t err = PLIST_ERR_SUCCESS; 1055 plist_err_t err = PLIST_ERR_SUCCESS;
1038 for (ch = node_first_child(node); ch; ch = node_next_sibling(ch)) { 1056 for (ch = node_first_child(node); ch; ch = node_next_sibling(ch)) {
1039 err = serialize_plist(ch, data); 1057 err = serialize_plist(ch, data, depth+1);
1040 if (err != PLIST_ERR_SUCCESS) { 1058 if (err != PLIST_ERR_SUCCESS) {
1041 break; 1059 break;
1042 } 1060 }
@@ -1313,7 +1331,7 @@ plist_err_t plist_to_bin(plist_t plist, char **plist_bin, uint32_t * length)
1313 ser_s.objects = objects; 1331 ser_s.objects = objects;
1314 ser_s.ref_table = ref_table; 1332 ser_s.ref_table = ref_table;
1315 ser_s.in_stack = in_stack; 1333 ser_s.in_stack = in_stack;
1316 plist_err_t err = serialize_plist((node_t)plist, &ser_s); 1334 plist_err_t err = serialize_plist((node_t)plist, &ser_s, 0);
1317 if (err != PLIST_ERR_SUCCESS) { 1335 if (err != PLIST_ERR_SUCCESS) {
1318 ptr_array_free(objects); 1336 ptr_array_free(objects);
1319 hash_table_destroy(ref_table); 1337 hash_table_destroy(ref_table);