summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/bplist.c24
1 files changed, 14 insertions, 10 deletions
diff --git a/src/bplist.c b/src/bplist.c
index 7d21b27..eede7a7 100644
--- a/src/bplist.c
+++ b/src/bplist.c
@@ -561,6 +561,8 @@ static plist_t parse_bin_node(struct bplist_data *bplist, const char** object)
561{ 561{
562 uint16_t type = 0; 562 uint16_t type = 0;
563 uint64_t size = 0; 563 uint64_t size = 0;
564 uint64_t pobject = 0;
565 uint64_t poffset_table = (uint64_t)bplist->offset_table;
564 566
565 if (!object) 567 if (!object)
566 return NULL; 568 return NULL;
@@ -598,6 +600,8 @@ static plist_t parse_bin_node(struct bplist_data *bplist, const char** object)
598 } 600 }
599 } 601 }
600 602
603 pobject = (uint64_t)*object;
604
601 switch (type) 605 switch (type)
602 { 606 {
603 607
@@ -629,14 +633,14 @@ static plist_t parse_bin_node(struct bplist_data *bplist, const char** object)
629 } 633 }
630 634
631 case BPLIST_UINT: 635 case BPLIST_UINT:
632 if (*object + (uint64_t)(1 << size) > bplist->offset_table) { 636 if (pobject + (uint64_t)(1 << size) > poffset_table) {
633 PLIST_BIN_ERR("%s: BPLIST_UINT data bytes point outside of valid range\n", __func__); 637 PLIST_BIN_ERR("%s: BPLIST_UINT data bytes point outside of valid range\n", __func__);
634 return NULL; 638 return NULL;
635 } 639 }
636 return parse_uint_node(object, size); 640 return parse_uint_node(object, size);
637 641
638 case BPLIST_REAL: 642 case BPLIST_REAL:
639 if (*object + (uint64_t)(1 << size) > bplist->offset_table) { 643 if (pobject + (uint64_t)(1 << size) > poffset_table) {
640 PLIST_BIN_ERR("%s: BPLIST_REAL data bytes point outside of valid range\n", __func__); 644 PLIST_BIN_ERR("%s: BPLIST_REAL data bytes point outside of valid range\n", __func__);
641 return NULL; 645 return NULL;
642 } 646 }
@@ -647,21 +651,21 @@ static plist_t parse_bin_node(struct bplist_data *bplist, const char** object)
647 PLIST_BIN_ERR("%s: invalid data size for BPLIST_DATE node\n", __func__); 651 PLIST_BIN_ERR("%s: invalid data size for BPLIST_DATE node\n", __func__);
648 return NULL; 652 return NULL;
649 } 653 }
650 if (*object + (uint64_t)(1 << size) > bplist->offset_table) { 654 if (pobject + (uint64_t)(1 << size) > poffset_table) {
651 PLIST_BIN_ERR("%s: BPLIST_DATE data bytes point outside of valid range\n", __func__); 655 PLIST_BIN_ERR("%s: BPLIST_DATE data bytes point outside of valid range\n", __func__);
652 return NULL; 656 return NULL;
653 } 657 }
654 return parse_date_node(object, size); 658 return parse_date_node(object, size);
655 659
656 case BPLIST_DATA: 660 case BPLIST_DATA:
657 if (*object + size < *object || *object + size > bplist->offset_table) { 661 if (pobject + size < pobject || pobject + size > poffset_table) {
658 PLIST_BIN_ERR("%s: BPLIST_DATA data bytes point outside of valid range\n", __func__); 662 PLIST_BIN_ERR("%s: BPLIST_DATA data bytes point outside of valid range\n", __func__);
659 return NULL; 663 return NULL;
660 } 664 }
661 return parse_data_node(object, size); 665 return parse_data_node(object, size);
662 666
663 case BPLIST_STRING: 667 case BPLIST_STRING:
664 if (*object + size < *object || *object + size > bplist->offset_table) { 668 if (pobject + size < pobject || pobject + size > poffset_table) {
665 PLIST_BIN_ERR("%s: BPLIST_STRING data bytes point outside of valid range\n", __func__); 669 PLIST_BIN_ERR("%s: BPLIST_STRING data bytes point outside of valid range\n", __func__);
666 return NULL; 670 return NULL;
667 } 671 }
@@ -672,7 +676,7 @@ static plist_t parse_bin_node(struct bplist_data *bplist, const char** object)
672 PLIST_BIN_ERR("%s: Integer overflow when calculating BPLIST_UNICODE data size.\n", __func__); 676 PLIST_BIN_ERR("%s: Integer overflow when calculating BPLIST_UNICODE data size.\n", __func__);
673 return NULL; 677 return NULL;
674 } 678 }
675 if (*object + size*2 < *object || *object + size*2 > bplist->offset_table) { 679 if (pobject + size*2 < pobject || pobject + size*2 > poffset_table) {
676 PLIST_BIN_ERR("%s: BPLIST_UNICODE data bytes point outside of valid range\n", __func__); 680 PLIST_BIN_ERR("%s: BPLIST_UNICODE data bytes point outside of valid range\n", __func__);
677 return NULL; 681 return NULL;
678 } 682 }
@@ -680,21 +684,21 @@ static plist_t parse_bin_node(struct bplist_data *bplist, const char** object)
680 684
681 case BPLIST_SET: 685 case BPLIST_SET:
682 case BPLIST_ARRAY: 686 case BPLIST_ARRAY:
683 if (*object + size < *object || *object + size > bplist->offset_table) { 687 if (pobject + size < pobject || pobject + size > poffset_table) {
684 PLIST_BIN_ERR("%s: BPLIST_ARRAY data bytes point outside of valid range\n", __func__); 688 PLIST_BIN_ERR("%s: BPLIST_ARRAY data bytes point outside of valid range\n", __func__);
685 return NULL; 689 return NULL;
686 } 690 }
687 return parse_array_node(bplist, object, size); 691 return parse_array_node(bplist, object, size);
688 692
689 case BPLIST_UID: 693 case BPLIST_UID:
690 if (*object + size+1 > bplist->offset_table) { 694 if (pobject + size+1 > poffset_table) {
691 PLIST_BIN_ERR("%s: BPLIST_UID data bytes point outside of valid range\n", __func__); 695 PLIST_BIN_ERR("%s: BPLIST_UID data bytes point outside of valid range\n", __func__);
692 return NULL; 696 return NULL;
693 } 697 }
694 return parse_uid_node(object, size); 698 return parse_uid_node(object, size);
695 699
696 case BPLIST_DICT: 700 case BPLIST_DICT:
697 if (*object + size < *object || *object + size > bplist->offset_table) { 701 if (pobject + size < pobject || pobject + size > poffset_table) {
698 PLIST_BIN_ERR("%s: BPLIST_DICT data bytes point outside of valid range\n", __func__); 702 PLIST_BIN_ERR("%s: BPLIST_DICT data bytes point outside of valid range\n", __func__);
699 return NULL; 703 return NULL;
700 } 704 }
@@ -830,7 +834,7 @@ PLIST_API void plist_from_bin(const char *plist_bin, uint32_t length, plist_t *
830 return; 834 return;
831 } 835 }
832 836
833 if (offset_table + num_objects * offset_size > end_data) { 837 if ((uint64_t)offset_table + num_objects * offset_size > (uint64_t)end_data) {
834 PLIST_BIN_ERR("offset table points outside of valid range\n"); 838 PLIST_BIN_ERR("offset table points outside of valid range\n");
835 return; 839 return;
836 } 840 }