diff options
| author | 2017-02-05 06:01:11 +0100 | |
|---|---|---|
| committer | 2017-02-05 06:01:11 +0100 | |
| commit | 31d7cc5370f37cc6b9ecc4e26256e74634554343 (patch) | |
| tree | 85d35012ca641e012c1d9c8acd2fd76c5dfb81a8 /src/bplist.c | |
| parent | 67eb54ab73f07560ae72058ed6ab6b47936be695 (diff) | |
| download | libplist-31d7cc5370f37cc6b9ecc4e26256e74634554343.tar.gz libplist-31d7cc5370f37cc6b9ecc4e26256e74634554343.tar.bz2 | |
bplist: Add error/debug logging (only if configured with --enable-debug)
This commit adds proper debug/error messages being printed if the binary
plist parser encounters anything abnormal. To enable debug logging,
libplist must be configured with --enable-debug, and the environment
variable PLIST_BIN_DEBUG must be set to "1".
Diffstat (limited to 'src/bplist.c')
| -rw-r--r-- | src/bplist.c | 143 |
1 files changed, 112 insertions, 31 deletions
diff --git a/src/bplist.c b/src/bplist.c index 474025b..73202ff 100644 --- a/src/bplist.c +++ b/src/bplist.c | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | * bplist.c | 2 | * bplist.c |
| 3 | * Binary plist implementation | 3 | * Binary plist implementation |
| 4 | * | 4 | * |
| 5 | * Copyright (c) 2011-2016 Nikias Bassen, All Rights Reserved. | 5 | * Copyright (c) 2011-2017 Nikias Bassen, All Rights Reserved. |
| 6 | * Copyright (c) 2008-2010 Jonathan Beck, All Rights Reserved. | 6 | * Copyright (c) 2008-2010 Jonathan Beck, All Rights Reserved. |
| 7 | * | 7 | * |
| 8 | * This library is free software; you can redistribute it and/or | 8 | * This library is free software; you can redistribute it and/or |
| @@ -190,6 +190,29 @@ struct bplist_data { | |||
| 190 | plist_t used_indexes; | 190 | plist_t used_indexes; |
| 191 | }; | 191 | }; |
| 192 | 192 | ||
| 193 | #ifdef DEBUG | ||
| 194 | static int plist_bin_debug = 0; | ||
| 195 | #define PLIST_BIN_ERR(...) if (plist_bin_debug) { fprintf(stderr, "libplist[binparser] ERROR: " __VA_ARGS__); } | ||
| 196 | #else | ||
| 197 | #define PLIST_BIN_ERR(...) | ||
| 198 | #endif | ||
| 199 | |||
| 200 | void plist_bin_init(void) | ||
| 201 | { | ||
| 202 | /* init binary plist stuff */ | ||
| 203 | #ifdef DEBUG | ||
| 204 | char *env_debug = getenv("PLIST_BIN_DEBUG"); | ||
| 205 | if (env_debug && !strcmp(env_debug, "1")) { | ||
| 206 | plist_bin_debug = 1; | ||
| 207 | } | ||
| 208 | #endif | ||
| 209 | } | ||
| 210 | |||
| 211 | void plist_bin_deinit(void) | ||
| 212 | { | ||
| 213 | /* deinit binary plist stuff */ | ||
| 214 | } | ||
| 215 | |||
| 193 | static plist_t parse_bin_node_at_index(struct bplist_data *bplist, uint32_t node_index); | 216 | static plist_t parse_bin_node_at_index(struct bplist_data *bplist, uint32_t node_index); |
| 194 | 217 | ||
| 195 | static plist_t parse_uint_node(const char **bnode, uint8_t size) | 218 | static plist_t parse_uint_node(const char **bnode, uint8_t size) |
| @@ -210,6 +233,7 @@ static plist_t parse_uint_node(const char **bnode, uint8_t size) | |||
| 210 | break; | 233 | break; |
| 211 | default: | 234 | default: |
| 212 | free(data); | 235 | free(data); |
| 236 | PLIST_BIN_ERR("%s: Invalid byte size for integer node\n", __func__); | ||
| 213 | return NULL; | 237 | return NULL; |
| 214 | }; | 238 | }; |
| 215 | 239 | ||
| @@ -239,6 +263,7 @@ static plist_t parse_real_node(const char **bnode, uint8_t size) | |||
| 239 | break; | 263 | break; |
| 240 | default: | 264 | default: |
| 241 | free(data); | 265 | free(data); |
| 266 | PLIST_BIN_ERR("%s: Invalid byte size for real node\n", __func__); | ||
| 242 | return NULL; | 267 | return NULL; |
| 243 | } | 268 | } |
| 244 | data->type = PLIST_REAL; | 269 | data->type = PLIST_REAL; |
| @@ -275,7 +300,7 @@ static char *plist_utf16_to_utf8(uint16_t *unistr, long len, long *items_read, l | |||
| 275 | if (!unistr || (len <= 0)) return NULL; | 300 | if (!unistr || (len <= 0)) return NULL; |
| 276 | char *outbuf = (char*)malloc(4*(len+1)); | 301 | char *outbuf = (char*)malloc(4*(len+1)); |
| 277 | int p = 0; | 302 | int p = 0; |
| 278 | int i = 0; | 303 | long i = 0; |
| 279 | 304 | ||
| 280 | uint16_t wc; | 305 | uint16_t wc; |
| 281 | uint32_t w; | 306 | uint32_t w; |
| @@ -391,6 +416,7 @@ static plist_t parse_dict_node(struct bplist_data *bplist, const char** bnode, u | |||
| 391 | if ((index1_ptr < bplist->data || index1_ptr + bplist->ref_size > bplist->offset_table) || | 416 | if ((index1_ptr < bplist->data || index1_ptr + bplist->ref_size > bplist->offset_table) || |
| 392 | (index2_ptr < bplist->data || index2_ptr + bplist->ref_size > bplist->offset_table)) { | 417 | (index2_ptr < bplist->data || index2_ptr + bplist->ref_size > bplist->offset_table)) { |
| 393 | plist_free(node); | 418 | plist_free(node); |
| 419 | PLIST_BIN_ERR("%s: dict entry %llu is outside of valid range\n", __func__, j); | ||
| 394 | return NULL; | 420 | return NULL; |
| 395 | } | 421 | } |
| 396 | 422 | ||
| @@ -399,10 +425,12 @@ static plist_t parse_dict_node(struct bplist_data *bplist, const char** bnode, u | |||
| 399 | 425 | ||
| 400 | if (index1 >= bplist->num_objects) { | 426 | if (index1 >= bplist->num_objects) { |
| 401 | plist_free(node); | 427 | plist_free(node); |
| 428 | PLIST_BIN_ERR("%s: dict entry %llu key index (%llu) must be smaller than the number of objects (%llu)\n", __func__, j, index1, bplist->num_objects); | ||
| 402 | return NULL; | 429 | return NULL; |
| 403 | } | 430 | } |
| 404 | if (index2 >= bplist->num_objects) { | 431 | if (index2 >= bplist->num_objects) { |
| 405 | plist_free(node); | 432 | plist_free(node); |
| 433 | PLIST_BIN_ERR("%s: dict entry %llu value index (%llu) must be smaller than the number of objects (%llu)\n", __func__, j, index1, bplist->num_objects); | ||
| 406 | return NULL; | 434 | return NULL; |
| 407 | } | 435 | } |
| 408 | 436 | ||
| @@ -414,7 +442,7 @@ static plist_t parse_dict_node(struct bplist_data *bplist, const char** bnode, u | |||
| 414 | } | 442 | } |
| 415 | 443 | ||
| 416 | if (plist_get_data(key)->type != PLIST_STRING) { | 444 | if (plist_get_data(key)->type != PLIST_STRING) { |
| 417 | fprintf(stderr, "ERROR: Malformed binary plist dict, invalid node type for key!\n"); | 445 | PLIST_BIN_ERR("%s: malformed binary plist dict, invalid node type for key!\n", __func__); |
| 418 | plist_free(node); | 446 | plist_free(node); |
| 419 | return NULL; | 447 | return NULL; |
| 420 | } | 448 | } |
| @@ -422,7 +450,7 @@ static plist_t parse_dict_node(struct bplist_data *bplist, const char** bnode, u | |||
| 422 | /* enforce key type */ | 450 | /* enforce key type */ |
| 423 | plist_get_data(key)->type = PLIST_KEY; | 451 | plist_get_data(key)->type = PLIST_KEY; |
| 424 | if (!plist_get_data(key)->strval) { | 452 | if (!plist_get_data(key)->strval) { |
| 425 | fprintf(stderr, "ERROR: Malformed binary plist dict, invalid key node encountered!\n"); | 453 | PLIST_BIN_ERR("%s: malformed binary plist dict, invalid key node encountered!\n", __func__); |
| 426 | plist_free(key); | 454 | plist_free(key); |
| 427 | plist_free(node); | 455 | plist_free(node); |
| 428 | return NULL; | 456 | return NULL; |
| @@ -462,6 +490,7 @@ static plist_t parse_array_node(struct bplist_data *bplist, const char** bnode, | |||
| 462 | 490 | ||
| 463 | if (index1_ptr < bplist->data || index1_ptr + bplist->ref_size > bplist->offset_table) { | 491 | if (index1_ptr < bplist->data || index1_ptr + bplist->ref_size > bplist->offset_table) { |
| 464 | plist_free(node); | 492 | plist_free(node); |
| 493 | PLIST_BIN_ERR("%s: array item %llu is outside of valid range\n", __func__, j); | ||
| 465 | return NULL; | 494 | return NULL; |
| 466 | } | 495 | } |
| 467 | 496 | ||
| @@ -469,6 +498,7 @@ static plist_t parse_array_node(struct bplist_data *bplist, const char** bnode, | |||
| 469 | 498 | ||
| 470 | if (index1 >= bplist->num_objects) { | 499 | if (index1 >= bplist->num_objects) { |
| 471 | plist_free(node); | 500 | plist_free(node); |
| 501 | PLIST_BIN_ERR("%s: array item %llu object index (%llu) must be smaller than the number of objects (%llu)\n", __func__, j, index1, bplist->num_objects); | ||
| 472 | return NULL; | 502 | return NULL; |
| 473 | } | 503 | } |
| 474 | 504 | ||
| @@ -491,6 +521,7 @@ static plist_t parse_uid_node(const char **bnode, uint8_t size) | |||
| 491 | size = size + 1; | 521 | size = size + 1; |
| 492 | data->intval = UINT_TO_HOST(*bnode, size); | 522 | data->intval = UINT_TO_HOST(*bnode, size); |
| 493 | if (data->intval > UINT32_MAX) { | 523 | if (data->intval > UINT32_MAX) { |
| 524 | PLIST_BIN_ERR("%s: value %llu too large for UID node (must be <= %u)\n", __func__, (uint64_t)data->intval, UINT32_MAX); | ||
| 494 | free(data); | 525 | free(data); |
| 495 | return NULL; | 526 | return NULL; |
| 496 | } | 527 | } |
| @@ -524,12 +555,16 @@ static plist_t parse_bin_node(struct bplist_data *bplist, const char** object) | |||
| 524 | case BPLIST_DICT: | 555 | case BPLIST_DICT: |
| 525 | { | 556 | { |
| 526 | uint16_t next_size = **object & BPLIST_FILL; | 557 | uint16_t next_size = **object & BPLIST_FILL; |
| 527 | if ((**object & BPLIST_MASK) != BPLIST_UINT) | 558 | if ((**object & BPLIST_MASK) != BPLIST_UINT) { |
| 559 | PLIST_BIN_ERR("%s: invalid size node type for node type 0x%02x: found 0x%02x, expected 0x%02x\n", __func__, type, **object & BPLIST_MASK, BPLIST_UINT); | ||
| 528 | return NULL; | 560 | return NULL; |
| 561 | } | ||
| 529 | (*object)++; | 562 | (*object)++; |
| 530 | next_size = 1 << next_size; | 563 | next_size = 1 << next_size; |
| 531 | if (*object + next_size > bplist->offset_table) | 564 | if (*object + next_size > bplist->offset_table) { |
| 565 | PLIST_BIN_ERR("%s: size node data bytes for node type 0x%02x point outside of valid range\n", __func__, type); | ||
| 532 | return NULL; | 566 | return NULL; |
| 567 | } | ||
| 533 | size = UINT_TO_HOST(*object, next_size); | 568 | size = UINT_TO_HOST(*object, next_size); |
| 534 | (*object) += next_size; | 569 | (*object) += next_size; |
| 535 | break; | 570 | break; |
| @@ -570,54 +605,75 @@ static plist_t parse_bin_node(struct bplist_data *bplist, const char** object) | |||
| 570 | } | 605 | } |
| 571 | 606 | ||
| 572 | case BPLIST_UINT: | 607 | case BPLIST_UINT: |
| 573 | if (*object + (uint64_t)(1 << size) > bplist->offset_table) | 608 | if (*object + (uint64_t)(1 << size) > bplist->offset_table) { |
| 609 | PLIST_BIN_ERR("%s: BPLIST_UINT data bytes point outside of valid range\n", __func__); | ||
| 574 | return NULL; | 610 | return NULL; |
| 611 | } | ||
| 575 | return parse_uint_node(object, size); | 612 | return parse_uint_node(object, size); |
| 576 | 613 | ||
| 577 | case BPLIST_REAL: | 614 | case BPLIST_REAL: |
| 578 | if (*object + (uint64_t)(1 << size) > bplist->offset_table) | 615 | if (*object + (uint64_t)(1 << size) > bplist->offset_table) { |
| 616 | PLIST_BIN_ERR("%s: BPLIST_REAL data bytes point outside of valid range\n", __func__); | ||
| 579 | return NULL; | 617 | return NULL; |
| 618 | } | ||
| 580 | return parse_real_node(object, size); | 619 | return parse_real_node(object, size); |
| 581 | 620 | ||
| 582 | case BPLIST_DATE: | 621 | case BPLIST_DATE: |
| 583 | if (3 != size) | 622 | if (3 != size) { |
| 623 | PLIST_BIN_ERR("%s: invalid data size for BPLIST_DATE node\n", __func__); | ||
| 584 | return NULL; | 624 | return NULL; |
| 585 | if (*object + (uint64_t)(1 << size) > bplist->offset_table) | 625 | } |
| 626 | if (*object + (uint64_t)(1 << size) > bplist->offset_table) { | ||
| 627 | PLIST_BIN_ERR("%s: BPLIST_DATE data bytes point outside of valid range\n", __func__); | ||
| 586 | return NULL; | 628 | return NULL; |
| 629 | } | ||
| 587 | return parse_date_node(object, size); | 630 | return parse_date_node(object, size); |
| 588 | 631 | ||
| 589 | case BPLIST_DATA: | 632 | case BPLIST_DATA: |
| 590 | if (*object + size > bplist->offset_table) | 633 | if (*object + size > bplist->offset_table) { |
| 634 | PLIST_BIN_ERR("%s: BPLIST_DATA data bytes point outside of valid range\n", __func__); | ||
| 591 | return NULL; | 635 | return NULL; |
| 636 | } | ||
| 592 | return parse_data_node(object, size); | 637 | return parse_data_node(object, size); |
| 593 | 638 | ||
| 594 | case BPLIST_STRING: | 639 | case BPLIST_STRING: |
| 595 | if (*object + size > bplist->offset_table) | 640 | if (*object + size > bplist->offset_table) { |
| 641 | PLIST_BIN_ERR("%s: BPLIST_STRING data bytes point outside of valid range\n", __func__); | ||
| 596 | return NULL; | 642 | return NULL; |
| 643 | } | ||
| 597 | return parse_string_node(object, size); | 644 | return parse_string_node(object, size); |
| 598 | 645 | ||
| 599 | case BPLIST_UNICODE: | 646 | case BPLIST_UNICODE: |
| 600 | if (*object + size*2 > bplist->offset_table) | 647 | if (*object + size*2 > bplist->offset_table) { |
| 648 | PLIST_BIN_ERR("%s: BPLIST_UNICODE data bytes point outside of valid range\n", __func__); | ||
| 601 | return NULL; | 649 | return NULL; |
| 650 | } | ||
| 602 | return parse_unicode_node(object, size); | 651 | return parse_unicode_node(object, size); |
| 603 | 652 | ||
| 604 | case BPLIST_SET: | 653 | case BPLIST_SET: |
| 605 | case BPLIST_ARRAY: | 654 | case BPLIST_ARRAY: |
| 606 | if (*object + size > bplist->offset_table) | 655 | if (*object + size > bplist->offset_table) { |
| 656 | PLIST_BIN_ERR("%s: BPLIST_ARRAY data bytes point outside of valid range\n", __func__); | ||
| 607 | return NULL; | 657 | return NULL; |
| 658 | } | ||
| 608 | return parse_array_node(bplist, object, size); | 659 | return parse_array_node(bplist, object, size); |
| 609 | 660 | ||
| 610 | case BPLIST_UID: | 661 | case BPLIST_UID: |
| 611 | if (*object + size+1 > bplist->offset_table) | 662 | if (*object + size+1 > bplist->offset_table) { |
| 663 | PLIST_BIN_ERR("%s: BPLIST_UID data bytes point outside of valid range\n", __func__); | ||
| 612 | return NULL; | 664 | return NULL; |
| 665 | } | ||
| 613 | return parse_uid_node(object, size); | 666 | return parse_uid_node(object, size); |
| 614 | 667 | ||
| 615 | case BPLIST_DICT: | 668 | case BPLIST_DICT: |
| 616 | if (*object + size > bplist->offset_table) | 669 | if (*object + size > bplist->offset_table) { |
| 670 | PLIST_BIN_ERR("%s: BPLIST_REAL data bytes point outside of valid range\n", __func__); | ||
| 617 | return NULL; | 671 | return NULL; |
| 672 | } | ||
| 618 | return parse_dict_node(bplist, object, size); | 673 | return parse_dict_node(bplist, object, size); |
| 619 | 674 | ||
| 620 | default: | 675 | default: |
| 676 | PLIST_BIN_ERR("%s: unexpected node type 0x%02x\n", __func__, type); | ||
| 621 | return NULL; | 677 | return NULL; |
| 622 | } | 678 | } |
| 623 | return NULL; | 679 | return NULL; |
| @@ -630,17 +686,22 @@ static plist_t parse_bin_node_at_index(struct bplist_data *bplist, uint32_t node | |||
| 630 | plist_t plist = NULL; | 686 | plist_t plist = NULL; |
| 631 | const char* idx_ptr = NULL; | 687 | const char* idx_ptr = NULL; |
| 632 | 688 | ||
| 633 | if (node_index >= bplist->num_objects) | 689 | if (node_index >= bplist->num_objects) { |
| 690 | PLIST_BIN_ERR("node index (%u) must be smaller than the number of objects (%llu)\n", node_index, bplist->num_objects); | ||
| 634 | return NULL; | 691 | return NULL; |
| 692 | } | ||
| 635 | 693 | ||
| 636 | idx_ptr = bplist->offset_table + node_index * bplist->offset_size; | 694 | idx_ptr = bplist->offset_table + node_index * bplist->offset_size; |
| 637 | if (idx_ptr < bplist->offset_table || | 695 | if (idx_ptr < bplist->offset_table || |
| 638 | idx_ptr >= bplist->offset_table + bplist->num_objects * bplist->offset_size) | 696 | idx_ptr >= bplist->offset_table + bplist->num_objects * bplist->offset_size) { |
| 697 | PLIST_BIN_ERR("node index %u points outside of valid range\n", node_index); | ||
| 639 | return NULL; | 698 | return NULL; |
| 699 | } | ||
| 640 | 700 | ||
| 641 | ptr = bplist->data + UINT_TO_HOST(idx_ptr, bplist->offset_size); | 701 | ptr = bplist->data + UINT_TO_HOST(idx_ptr, bplist->offset_size); |
| 642 | /* make sure the node offset is in a sane range */ | 702 | /* make sure the node offset is in a sane range */ |
| 643 | if ((ptr < bplist->data) || (ptr >= bplist->offset_table)) { | 703 | if ((ptr < bplist->data) || (ptr >= bplist->offset_table)) { |
| 704 | PLIST_BIN_ERR("offset for node index %u points outside of valid range\n", node_index); | ||
| 644 | return NULL; | 705 | return NULL; |
| 645 | } | 706 | } |
| 646 | 707 | ||
| @@ -659,7 +720,7 @@ static plist_t parse_bin_node_at_index(struct bplist_data *bplist, uint32_t node | |||
| 659 | plist_t node_i = plist_array_get_item(bplist->used_indexes, i); | 720 | plist_t node_i = plist_array_get_item(bplist->used_indexes, i); |
| 660 | plist_t node_level = plist_array_get_item(bplist->used_indexes, bplist->level); | 721 | plist_t node_level = plist_array_get_item(bplist->used_indexes, bplist->level); |
| 661 | if (plist_compare_node_value(node_i, node_level)) { | 722 | if (plist_compare_node_value(node_i, node_level)) { |
| 662 | fprintf(stderr, "Recursion detected in binary plist. Aborting.\n"); | 723 | PLIST_BIN_ERR("recursion detected in binary plist\n"); |
| 663 | return NULL; | 724 | return NULL; |
| 664 | } | 725 | } |
| 665 | } | 726 | } |
| @@ -684,14 +745,20 @@ PLIST_API void plist_from_bin(const char *plist_bin, uint32_t length, plist_t * | |||
| 684 | const char *end_data = NULL; | 745 | const char *end_data = NULL; |
| 685 | 746 | ||
| 686 | //first check we have enough data | 747 | //first check we have enough data |
| 687 | if (!(length >= BPLIST_MAGIC_SIZE + BPLIST_VERSION_SIZE + sizeof(bplist_trailer_t))) | 748 | if (!(length >= BPLIST_MAGIC_SIZE + BPLIST_VERSION_SIZE + sizeof(bplist_trailer_t))) { |
| 749 | PLIST_BIN_ERR("plist data is to small to hold a binary plist\n"); | ||
| 688 | return; | 750 | return; |
| 751 | } | ||
| 689 | //check that plist_bin in actually a plist | 752 | //check that plist_bin in actually a plist |
| 690 | if (memcmp(plist_bin, BPLIST_MAGIC, BPLIST_MAGIC_SIZE) != 0) | 753 | if (memcmp(plist_bin, BPLIST_MAGIC, BPLIST_MAGIC_SIZE) != 0) { |
| 754 | PLIST_BIN_ERR("bplist magic mismatch\n"); | ||
| 691 | return; | 755 | return; |
| 756 | } | ||
| 692 | //check for known version | 757 | //check for known version |
| 693 | if (memcmp(plist_bin + BPLIST_MAGIC_SIZE, BPLIST_VERSION, BPLIST_VERSION_SIZE) != 0) | 758 | if (memcmp(plist_bin + BPLIST_MAGIC_SIZE, BPLIST_VERSION, BPLIST_VERSION_SIZE) != 0) { |
| 759 | PLIST_BIN_ERR("unsupported binary plist version '%.2s\n", plist_bin+BPLIST_MAGIC_SIZE); | ||
| 694 | return; | 760 | return; |
| 761 | } | ||
| 695 | 762 | ||
| 696 | start_data = plist_bin + BPLIST_MAGIC_SIZE + BPLIST_VERSION_SIZE; | 763 | start_data = plist_bin + BPLIST_MAGIC_SIZE + BPLIST_VERSION_SIZE; |
| 697 | end_data = plist_bin + length - sizeof(bplist_trailer_t); | 764 | end_data = plist_bin + length - sizeof(bplist_trailer_t); |
| @@ -705,23 +772,35 @@ PLIST_API void plist_from_bin(const char *plist_bin, uint32_t length, plist_t * | |||
| 705 | root_object = be64toh(trailer->root_object_index); | 772 | root_object = be64toh(trailer->root_object_index); |
| 706 | offset_table = (char *)(plist_bin + be64toh(trailer->offset_table_offset)); | 773 | offset_table = (char *)(plist_bin + be64toh(trailer->offset_table_offset)); |
| 707 | 774 | ||
| 708 | if (num_objects == 0) | 775 | if (num_objects == 0) { |
| 776 | PLIST_BIN_ERR("number of objects must be larger than 0\n"); | ||
| 709 | return; | 777 | return; |
| 778 | } | ||
| 710 | 779 | ||
| 711 | if (offset_size == 0) | 780 | if (offset_size == 0) { |
| 781 | PLIST_BIN_ERR("offset size in trailer must be larger than 0\n"); | ||
| 712 | return; | 782 | return; |
| 783 | } | ||
| 713 | 784 | ||
| 714 | if (ref_size == 0) | 785 | if (ref_size == 0) { |
| 786 | PLIST_BIN_ERR("object reference size in trailer must be larger than 0\n"); | ||
| 715 | return; | 787 | return; |
| 788 | } | ||
| 716 | 789 | ||
| 717 | if (root_object >= num_objects) | 790 | if (root_object >= num_objects) { |
| 791 | PLIST_BIN_ERR("root object index (%llu) must be smaller than number of objects (%llu)\n", root_object, num_objects); | ||
| 718 | return; | 792 | return; |
| 793 | } | ||
| 719 | 794 | ||
| 720 | if (offset_table < start_data || offset_table >= end_data) | 795 | if (offset_table < start_data || offset_table >= end_data) { |
| 796 | PLIST_BIN_ERR("offset table offset points outside of valid range\n"); | ||
| 721 | return; | 797 | return; |
| 798 | } | ||
| 722 | 799 | ||
| 723 | if (offset_table + num_objects * offset_size > end_data) | 800 | if (offset_table + num_objects * offset_size > end_data) { |
| 801 | PLIST_BIN_ERR("offset table points outside of valid range\n"); | ||
| 724 | return; | 802 | return; |
| 803 | } | ||
| 725 | 804 | ||
| 726 | struct bplist_data bplist; | 805 | struct bplist_data bplist; |
| 727 | bplist.data = plist_bin; | 806 | bplist.data = plist_bin; |
| @@ -733,8 +812,10 @@ PLIST_API void plist_from_bin(const char *plist_bin, uint32_t length, plist_t * | |||
| 733 | bplist.level = 0; | 812 | bplist.level = 0; |
| 734 | bplist.used_indexes = plist_new_array(); | 813 | bplist.used_indexes = plist_new_array(); |
| 735 | 814 | ||
| 736 | if (!bplist.used_indexes) | 815 | if (!bplist.used_indexes) { |
| 816 | PLIST_BIN_ERR("failed to create array to hold used node indexes. Out of memory?\n"); | ||
| 737 | return; | 817 | return; |
| 818 | } | ||
| 738 | 819 | ||
| 739 | *plist = parse_bin_node_at_index(&bplist, root_object); | 820 | *plist = parse_bin_node_at_index(&bplist, root_object); |
| 740 | 821 | ||
| @@ -983,7 +1064,7 @@ static uint16_t *plist_utf8_to_utf16(char *unistr, long size, long *items_read, | |||
| 983 | { | 1064 | { |
| 984 | uint16_t *outbuf = (uint16_t*)malloc(((size*2)+1)*sizeof(uint16_t)); | 1065 | uint16_t *outbuf = (uint16_t*)malloc(((size*2)+1)*sizeof(uint16_t)); |
| 985 | int p = 0; | 1066 | int p = 0; |
| 986 | int i = 0; | 1067 | long i = 0; |
| 987 | 1068 | ||
| 988 | unsigned char c0; | 1069 | unsigned char c0; |
| 989 | unsigned char c1; | 1070 | unsigned char c1; |
| @@ -1017,7 +1098,7 @@ static uint16_t *plist_utf8_to_utf16(char *unistr, long size, long *items_read, | |||
| 1017 | i+=1; | 1098 | i+=1; |
| 1018 | } else { | 1099 | } else { |
| 1019 | // invalid character | 1100 | // invalid character |
| 1020 | fprintf(stderr, "invalid utf8 sequence in string at index %d\n", i); | 1101 | PLIST_BIN_ERR("%s: invalid utf8 sequence in string at index %lu\n", __func__, i); |
| 1021 | break; | 1102 | break; |
| 1022 | } | 1103 | } |
| 1023 | } | 1104 | } |
