summaryrefslogtreecommitdiffstats
path: root/src/bplist.c
diff options
context:
space:
mode:
authorGravatar Nikias Bassen2017-01-25 03:28:29 +0100
committerGravatar Nikias Bassen2017-01-25 03:28:29 +0100
commit6bf56a7cb5e98a4afe4e969d343b9a50681afd97 (patch)
tree06a4f087f35073047e1aacad06e75610143bec98 /src/bplist.c
parent4c072d015193af74719d07897c0a0b4396b4a866 (diff)
downloadlibplist-6bf56a7cb5e98a4afe4e969d343b9a50681afd97.tar.gz
libplist-6bf56a7cb5e98a4afe4e969d343b9a50681afd97.tar.bz2
bplist: Fix UID node parsing to match Apple's parser
Apple only allows 32 bit unsigned values for UID nodes. Also the encoding of the length is different from the encoding used for other node types. The nibble used to mark the size is 1 less than the actual size of the integer value data, so 0 means 1 byte length 1 means 2 bytes length, etc.
Diffstat (limited to 'src/bplist.c')
-rw-r--r--src/bplist.c21
1 files changed, 7 insertions, 14 deletions
diff --git a/src/bplist.c b/src/bplist.c
index ad8e753..9e6e261 100644
--- a/src/bplist.c
+++ b/src/bplist.c
@@ -496,22 +496,14 @@ static plist_t parse_array_node(struct bplist_data *bplist, const char** bnode,
496static plist_t parse_uid_node(const char **bnode, uint8_t size) 496static plist_t parse_uid_node(const char **bnode, uint8_t size)
497{ 497{
498 plist_data_t data = plist_new_plist_data(); 498 plist_data_t data = plist_new_plist_data();
499 499 size = size + 1;
500 size = 1 << size; // make length less misleading 500 data->intval = UINT_TO_HOST(*bnode, size);
501 switch (size) 501 if (data->intval > UINT32_MAX) {
502 {
503 case sizeof(uint8_t):
504 case sizeof(uint16_t):
505 case sizeof(uint32_t):
506 case sizeof(uint64_t):
507 memcpy(&data->intval, *bnode, size);
508 data->intval = UINT_TO_HOST(&data->intval, size);
509 break;
510 default:
511 free(data); 502 free(data);
512 return NULL; 503 return NULL;
513 }; 504 }
514 505
506 (*bnode) += size;
515 data->type = PLIST_UID; 507 data->type = PLIST_UID;
516 data->length = sizeof(uint64_t); 508 data->length = sizeof(uint64_t);
517 509
@@ -1034,6 +1026,7 @@ static void write_dict(bytearray_t * bplist, node_t* node, hashtable_t* ref_tabl
1034 1026
1035static void write_uid(bytearray_t * bplist, uint64_t val) 1027static void write_uid(bytearray_t * bplist, uint64_t val)
1036{ 1028{
1029 val = (uint32_t)val;
1037 uint64_t size = get_needed_bytes(val); 1030 uint64_t size = get_needed_bytes(val);
1038 uint8_t *buff = NULL; 1031 uint8_t *buff = NULL;
1039 //do not write 3bytes int node 1032 //do not write 3bytes int node
@@ -1045,7 +1038,7 @@ static void write_uid(bytearray_t * bplist, uint64_t val)
1045#endif 1038#endif
1046 1039
1047 buff = (uint8_t *) malloc(sizeof(uint8_t) + size); 1040 buff = (uint8_t *) malloc(sizeof(uint8_t) + size);
1048 buff[0] = BPLIST_UID | Log2(size); 1041 buff[0] = BPLIST_UID | (size-1); // yes, this is what Apple does...
1049 memcpy(buff + 1, &val, size); 1042 memcpy(buff + 1, &val, size);
1050 byte_convert(buff + 1, size); 1043 byte_convert(buff + 1, size);
1051 byte_array_append(bplist, buff, sizeof(uint8_t) + size); 1044 byte_array_append(bplist, buff, sizeof(uint8_t) + size);