summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Martin Szulecki2014-10-09 22:26:18 +0200
committerGravatar Martin Szulecki2014-10-09 22:26:18 +0200
commitb3ab0a4276036cc89f431dafb81dc585b39a89f1 (patch)
treef1ac0efe888f1c755a0864696dc6c5d52c223973
parentae73b608abeaa92b59df9d226912fb1f692f58f6 (diff)
downloadlibplist-b3ab0a4276036cc89f431dafb81dc585b39a89f1.tar.gz
libplist-b3ab0a4276036cc89f431dafb81dc585b39a89f1.tar.bz2
bplist: Fix plist_from_bin() changing value nodes to key nodes in dictionaries
The parsing logic for binary dictionaries wrongly enforced the key type even on nodes that were already parsed as value nodes. This caused the resulting plist_t node tree to have key nodes instead of value nodes within dictionaries for some valid binary plists. This commit should also generally fixes parsing of binary plist files which use an efficient dictionary reference table.
-rw-r--r--src/bplist.c44
1 files changed, 33 insertions, 11 deletions
diff --git a/src/bplist.c b/src/bplist.c
index 6a9d972..40b453b 100644
--- a/src/bplist.c
+++ b/src/bplist.c
@@ -673,29 +673,51 @@ PLIST_API void plist_from_bin(const char *plist_bin, uint32_t length, plist_t *
673 case PLIST_DICT: 673 case PLIST_DICT:
674 for (j = 0; j < data->length; j++) 674 for (j = 0; j < data->length; j++)
675 { 675 {
676 node_t* n = NULL;
676 str_i = j * dict_param_size; 677 str_i = j * dict_param_size;
677 str_j = (j + data->length) * dict_param_size; 678 str_j = (j + data->length) * dict_param_size;
678 679
679 index1 = UINT_TO_HOST(data->buff + str_i, dict_param_size); 680 index1 = UINT_TO_HOST(data->buff + str_i, dict_param_size);
680 index2 = UINT_TO_HOST(data->buff + str_j, dict_param_size); 681 index2 = UINT_TO_HOST(data->buff + str_j, dict_param_size);
681 682
682 //first one is actually a key 683 // process key node
683 plist_get_data(nodeslist[index1])->type = PLIST_KEY;
684
685 if (index1 < num_objects) 684 if (index1 < num_objects)
686 { 685 {
687 if (NODE_IS_ROOT(nodeslist[index1])) 686 // is node already attached?
688 node_attach(nodeslist[i], nodeslist[index1]); 687 if (NODE_IS_ROOT(nodeslist[index1])) {
689 else 688 // use original
690 node_attach(nodeslist[i], node_copy_deep(nodeslist[index1], copy_plist_data)); 689 n = nodeslist[index1];
690 } else {
691 // use a copy, because this node is already attached elsewhere
692 n = node_copy_deep(nodeslist[index1], copy_plist_data);
693 }
694
695 // enforce key type
696 plist_get_data(n)->type = PLIST_KEY;
697
698 // attach key node
699 node_attach(nodeslist[i], n);
691 } 700 }
692 701
702 // process value node
693 if (index2 < num_objects) 703 if (index2 < num_objects)
694 { 704 {
695 if (NODE_IS_ROOT(nodeslist[index2])) 705 // is node already attached?
696 node_attach(nodeslist[i], nodeslist[index2]); 706 if (NODE_IS_ROOT(nodeslist[index2])) {
697 else 707 // use original
698 node_attach(nodeslist[i], node_copy_deep(nodeslist[index2], copy_plist_data)); 708 n = nodeslist[index2];
709 } else {
710 // use a copy, because this node is already attached elsewhere
711 n = node_copy_deep(nodeslist[index2], copy_plist_data);
712
713 // ensure key type is never used for values, especially if we copy a key node
714 if (plist_get_data(n)->type == PLIST_KEY) {
715 plist_get_data(n)->type = PLIST_STRING;
716 }
717 }
718
719 // attach value node
720 node_attach(nodeslist[i], n);
699 } 721 }
700 } 722 }
701 723