summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Nikias Bassen2017-02-01 18:50:00 +0100
committerGravatar Nikias Bassen2017-02-01 18:50:00 +0100
commite9895752a396c4acb8c2b4ba525c13329d4e9fab (patch)
treef64ce60a28630090708384d68f95a9d9d3be915d
parentcf9836196cbabd6d40e8c1c8018417ef31df5f46 (diff)
downloadlibplist-e9895752a396c4acb8c2b4ba525c13329d4e9fab.tar.gz
libplist-e9895752a396c4acb8c2b4ba525c13329d4e9fab.tar.bz2
bplist: Avoid heap buffer allocation when parsing array/dict/string/data node sizes > 14
The sizes where effectively parsed by calling parse_uint_node() which allocates a node_t (along with plist_data_t) that is immediately freed after retrieving the integer value it holds. This commit changes the code to directly operate on the binary stream to 'just' read the size instead, reducing the memory footprint further.
-rw-r--r--src/bplist.c45
1 files changed, 25 insertions, 20 deletions
diff --git a/src/bplist.c b/src/bplist.c
index 64c9081..2e32f70 100644
--- a/src/bplist.c
+++ b/src/bplist.c
@@ -557,11 +557,12 @@ static plist_t parse_bin_node(struct bplist_data *bplist, const char** object)
557 557
558 case BPLIST_DATA: 558 case BPLIST_DATA:
559 if (BPLIST_FILL == size) { 559 if (BPLIST_FILL == size) {
560 plist_t size_node = parse_bin_node(bplist, object); 560 uint8_t next_size = **object & BPLIST_FILL;
561 if (plist_get_node_type(size_node) != PLIST_UINT) 561 if ((**object & BPLIST_MASK) != BPLIST_UINT)
562 return NULL; 562 return NULL;
563 plist_get_uint_val(size_node, &size); 563 (*object)++;
564 plist_free(size_node); 564 size = UINT_TO_HOST(*object, (1 << next_size));
565 (*object) += (1 << next_size);
565 } 566 }
566 567
567 if (*object - bplist->data + size >= bplist->size) 568 if (*object - bplist->data + size >= bplist->size)
@@ -570,11 +571,12 @@ static plist_t parse_bin_node(struct bplist_data *bplist, const char** object)
570 571
571 case BPLIST_STRING: 572 case BPLIST_STRING:
572 if (BPLIST_FILL == size) { 573 if (BPLIST_FILL == size) {
573 plist_t size_node = parse_bin_node(bplist, object); 574 uint8_t next_size = **object & BPLIST_FILL;
574 if (plist_get_node_type(size_node) != PLIST_UINT) 575 if ((**object & BPLIST_MASK) != BPLIST_UINT)
575 return NULL; 576 return NULL;
576 plist_get_uint_val(size_node, &size); 577 (*object)++;
577 plist_free(size_node); 578 size = UINT_TO_HOST(*object, (1 << next_size));
579 (*object) += (1 << next_size);
578 } 580 }
579 581
580 if (*object - bplist->data + size >= bplist->size) 582 if (*object - bplist->data + size >= bplist->size)
@@ -583,11 +585,12 @@ static plist_t parse_bin_node(struct bplist_data *bplist, const char** object)
583 585
584 case BPLIST_UNICODE: 586 case BPLIST_UNICODE:
585 if (BPLIST_FILL == size) { 587 if (BPLIST_FILL == size) {
586 plist_t size_node = parse_bin_node(bplist, object); 588 uint8_t next_size = **object & BPLIST_FILL;
587 if (plist_get_node_type(size_node) != PLIST_UINT) 589 if ((**object & BPLIST_MASK) != BPLIST_UINT)
588 return NULL; 590 return NULL;
589 plist_get_uint_val(size_node, &size); 591 (*object)++;
590 plist_free(size_node); 592 size = UINT_TO_HOST(*object, (1 << next_size));
593 (*object) += (1 << next_size);
591 } 594 }
592 595
593 if (*object - bplist->data + size * 2 >= bplist->size) 596 if (*object - bplist->data + size * 2 >= bplist->size)
@@ -597,11 +600,12 @@ static plist_t parse_bin_node(struct bplist_data *bplist, const char** object)
597 case BPLIST_SET: 600 case BPLIST_SET:
598 case BPLIST_ARRAY: 601 case BPLIST_ARRAY:
599 if (BPLIST_FILL == size) { 602 if (BPLIST_FILL == size) {
600 plist_t size_node = parse_bin_node(bplist, object); 603 uint8_t next_size = **object & BPLIST_FILL;
601 if (plist_get_node_type(size_node) != PLIST_UINT) 604 if ((**object & BPLIST_MASK) != BPLIST_UINT)
602 return NULL; 605 return NULL;
603 plist_get_uint_val(size_node, &size); 606 (*object)++;
604 plist_free(size_node); 607 size = UINT_TO_HOST(*object, (1 << next_size));
608 (*object) += (1 << next_size);
605 } 609 }
606 610
607 if (*object - bplist->data + size >= bplist->size) 611 if (*object - bplist->data + size >= bplist->size)
@@ -613,11 +617,12 @@ static plist_t parse_bin_node(struct bplist_data *bplist, const char** object)
613 617
614 case BPLIST_DICT: 618 case BPLIST_DICT:
615 if (BPLIST_FILL == size) { 619 if (BPLIST_FILL == size) {
616 plist_t size_node = parse_bin_node(bplist, object); 620 uint8_t next_size = **object & BPLIST_FILL;
617 if (plist_get_node_type(size_node) != PLIST_UINT) 621 if ((**object & BPLIST_MASK) != BPLIST_UINT)
618 return NULL; 622 return NULL;
619 plist_get_uint_val(size_node, &size); 623 (*object)++;
620 plist_free(size_node); 624 size = UINT_TO_HOST(*object, (1 << next_size));
625 (*object) += (1 << next_size);
621 } 626 }
622 627
623 if (*object - bplist->data + size >= bplist->size) 628 if (*object - bplist->data + size >= bplist->size)