diff options
Diffstat (limited to 'src/plist.c')
| -rw-r--r-- | src/plist.c | 116 |
1 files changed, 103 insertions, 13 deletions
diff --git a/src/plist.c b/src/plist.c index ea285e0..22ef4d7 100644 --- a/src/plist.c +++ b/src/plist.c | |||
| @@ -358,8 +358,7 @@ plist_data_t plist_get_data(plist_t node) | |||
| 358 | 358 | ||
| 359 | plist_data_t plist_new_plist_data(void) | 359 | plist_data_t plist_new_plist_data(void) |
| 360 | { | 360 | { |
| 361 | plist_data_t data = (plist_data_t) calloc(1, sizeof(struct plist_data_s)); | 361 | return (plist_data_t) calloc(1, sizeof(struct plist_data_s)); |
| 362 | return data; | ||
| 363 | } | 362 | } |
| 364 | 363 | ||
| 365 | static unsigned int dict_key_hash(const void *data) | 364 | static unsigned int dict_key_hash(const void *data) |
| @@ -471,6 +470,10 @@ static int plist_free_node(node_t root) | |||
| 471 | plist_t plist_new_dict(void) | 470 | plist_t plist_new_dict(void) |
| 472 | { | 471 | { |
| 473 | plist_data_t data = plist_new_plist_data(); | 472 | plist_data_t data = plist_new_plist_data(); |
| 473 | if (!data) { | ||
| 474 | PLIST_ERR("%s: failed to allocate plist data\n", __func__); | ||
| 475 | return NULL; | ||
| 476 | } | ||
| 474 | data->type = PLIST_DICT; | 477 | data->type = PLIST_DICT; |
| 475 | return plist_new_node(data); | 478 | return plist_new_node(data); |
| 476 | } | 479 | } |
| @@ -478,6 +481,10 @@ plist_t plist_new_dict(void) | |||
| 478 | plist_t plist_new_array(void) | 481 | plist_t plist_new_array(void) |
| 479 | { | 482 | { |
| 480 | plist_data_t data = plist_new_plist_data(); | 483 | plist_data_t data = plist_new_plist_data(); |
| 484 | if (!data) { | ||
| 485 | PLIST_ERR("%s: failed to allocate plist data\n", __func__); | ||
| 486 | return NULL; | ||
| 487 | } | ||
| 481 | data->type = PLIST_ARRAY; | 488 | data->type = PLIST_ARRAY; |
| 482 | return plist_new_node(data); | 489 | return plist_new_node(data); |
| 483 | } | 490 | } |
| @@ -486,24 +493,48 @@ plist_t plist_new_array(void) | |||
| 486 | static plist_t plist_new_key(const char *val) | 493 | static plist_t plist_new_key(const char *val) |
| 487 | { | 494 | { |
| 488 | plist_data_t data = plist_new_plist_data(); | 495 | plist_data_t data = plist_new_plist_data(); |
| 496 | if (!data) { | ||
| 497 | PLIST_ERR("%s: failed to allocate plist data\n", __func__); | ||
| 498 | return NULL; | ||
| 499 | } | ||
| 489 | data->type = PLIST_KEY; | 500 | data->type = PLIST_KEY; |
| 490 | data->strval = strdup(val); | 501 | data->strval = strdup(val); |
| 491 | data->length = strlen(val); | 502 | if (!data->strval) { |
| 503 | plist_free_data(data); | ||
| 504 | PLIST_ERR("%s: strdup failed\n", __func__); | ||
| 505 | return NULL; | ||
| 506 | } else { | ||
| 507 | data->length = strlen(val); | ||
| 508 | } | ||
| 492 | return plist_new_node(data); | 509 | return plist_new_node(data); |
| 493 | } | 510 | } |
| 494 | 511 | ||
| 495 | plist_t plist_new_string(const char *val) | 512 | plist_t plist_new_string(const char *val) |
| 496 | { | 513 | { |
| 497 | plist_data_t data = plist_new_plist_data(); | 514 | plist_data_t data = plist_new_plist_data(); |
| 515 | if (!data) { | ||
| 516 | PLIST_ERR("%s: failed to allocate plist data\n", __func__); | ||
| 517 | return NULL; | ||
| 518 | } | ||
| 498 | data->type = PLIST_STRING; | 519 | data->type = PLIST_STRING; |
| 499 | data->strval = strdup(val); | 520 | data->strval = strdup(val); |
| 500 | data->length = strlen(val); | 521 | if (!data->strval) { |
| 522 | plist_free_data(data); | ||
| 523 | PLIST_ERR("%s: strdup failed\n", __func__); | ||
| 524 | return NULL; | ||
| 525 | } else { | ||
| 526 | data->length = strlen(val); | ||
| 527 | } | ||
| 501 | return plist_new_node(data); | 528 | return plist_new_node(data); |
| 502 | } | 529 | } |
| 503 | 530 | ||
| 504 | plist_t plist_new_bool(uint8_t val) | 531 | plist_t plist_new_bool(uint8_t val) |
| 505 | { | 532 | { |
| 506 | plist_data_t data = plist_new_plist_data(); | 533 | plist_data_t data = plist_new_plist_data(); |
| 534 | if (!data) { | ||
| 535 | PLIST_ERR("%s: failed to allocate plist data\n", __func__); | ||
| 536 | return NULL; | ||
| 537 | } | ||
| 507 | data->type = PLIST_BOOLEAN; | 538 | data->type = PLIST_BOOLEAN; |
| 508 | data->boolval = val; | 539 | data->boolval = val; |
| 509 | data->length = sizeof(uint8_t); | 540 | data->length = sizeof(uint8_t); |
| @@ -513,6 +544,10 @@ plist_t plist_new_bool(uint8_t val) | |||
| 513 | plist_t plist_new_uint(uint64_t val) | 544 | plist_t plist_new_uint(uint64_t val) |
| 514 | { | 545 | { |
| 515 | plist_data_t data = plist_new_plist_data(); | 546 | plist_data_t data = plist_new_plist_data(); |
| 547 | if (!data) { | ||
| 548 | PLIST_ERR("%s: failed to allocate plist data\n", __func__); | ||
| 549 | return NULL; | ||
| 550 | } | ||
| 516 | data->type = PLIST_INT; | 551 | data->type = PLIST_INT; |
| 517 | data->intval = val; | 552 | data->intval = val; |
| 518 | data->length = (val > INT_MAX) ? sizeof(uint64_t)*2 : sizeof(uint64_t); | 553 | data->length = (val > INT_MAX) ? sizeof(uint64_t)*2 : sizeof(uint64_t); |
| @@ -522,6 +557,10 @@ plist_t plist_new_uint(uint64_t val) | |||
| 522 | plist_t plist_new_int(int64_t val) | 557 | plist_t plist_new_int(int64_t val) |
| 523 | { | 558 | { |
| 524 | plist_data_t data = plist_new_plist_data(); | 559 | plist_data_t data = plist_new_plist_data(); |
| 560 | if (!data) { | ||
| 561 | PLIST_ERR("%s: failed to allocate plist data\n", __func__); | ||
| 562 | return NULL; | ||
| 563 | } | ||
| 525 | data->type = PLIST_INT; | 564 | data->type = PLIST_INT; |
| 526 | data->intval = val; | 565 | data->intval = val; |
| 527 | data->length = sizeof(uint64_t); | 566 | data->length = sizeof(uint64_t); |
| @@ -531,6 +570,10 @@ plist_t plist_new_int(int64_t val) | |||
| 531 | plist_t plist_new_uid(uint64_t val) | 570 | plist_t plist_new_uid(uint64_t val) |
| 532 | { | 571 | { |
| 533 | plist_data_t data = plist_new_plist_data(); | 572 | plist_data_t data = plist_new_plist_data(); |
| 573 | if (!data) { | ||
| 574 | PLIST_ERR("%s: failed to allocate plist data\n", __func__); | ||
| 575 | return NULL; | ||
| 576 | } | ||
| 534 | data->type = PLIST_UID; | 577 | data->type = PLIST_UID; |
| 535 | data->intval = val; | 578 | data->intval = val; |
| 536 | data->length = sizeof(uint64_t); | 579 | data->length = sizeof(uint64_t); |
| @@ -540,6 +583,10 @@ plist_t plist_new_uid(uint64_t val) | |||
| 540 | plist_t plist_new_real(double val) | 583 | plist_t plist_new_real(double val) |
| 541 | { | 584 | { |
| 542 | plist_data_t data = plist_new_plist_data(); | 585 | plist_data_t data = plist_new_plist_data(); |
| 586 | if (!data) { | ||
| 587 | PLIST_ERR("%s: failed to allocate plist data\n", __func__); | ||
| 588 | return NULL; | ||
| 589 | } | ||
| 543 | data->type = PLIST_REAL; | 590 | data->type = PLIST_REAL; |
| 544 | data->realval = val; | 591 | data->realval = val; |
| 545 | data->length = sizeof(double); | 592 | data->length = sizeof(double); |
| @@ -549,11 +596,19 @@ plist_t plist_new_real(double val) | |||
| 549 | plist_t plist_new_data(const char *val, uint64_t length) | 596 | plist_t plist_new_data(const char *val, uint64_t length) |
| 550 | { | 597 | { |
| 551 | plist_data_t data = plist_new_plist_data(); | 598 | plist_data_t data = plist_new_plist_data(); |
| 599 | if (!data) { | ||
| 600 | PLIST_ERR("%s: failed to allocate plist data\n", __func__); | ||
| 601 | return NULL; | ||
| 602 | } | ||
| 552 | data->type = PLIST_DATA; | 603 | data->type = PLIST_DATA; |
| 553 | if (val && length) { | 604 | if (val && length) { |
| 554 | data->buff = (uint8_t *) malloc(length); | 605 | data->buff = (uint8_t *) malloc(length); |
| 555 | memcpy(data->buff, val, length); | 606 | if (!data->buff) { |
| 556 | } | 607 | PLIST_ERR("%s: failed to allocate %" PRIu64 " bytes\n", __func__, length); |
| 608 | return NULL; | ||
| 609 | } | ||
| 610 | memcpy(data->buff, val, length); | ||
| 611 | } | ||
| 557 | data->length = length; | 612 | data->length = length; |
| 558 | return plist_new_node(data); | 613 | return plist_new_node(data); |
| 559 | } | 614 | } |
| @@ -561,6 +616,10 @@ if (val && length) { | |||
| 561 | plist_t plist_new_date(int32_t sec, int32_t usec) | 616 | plist_t plist_new_date(int32_t sec, int32_t usec) |
| 562 | { | 617 | { |
| 563 | plist_data_t data = plist_new_plist_data(); | 618 | plist_data_t data = plist_new_plist_data(); |
| 619 | if (!data) { | ||
| 620 | PLIST_ERR("%s: failed to allocate plist data\n", __func__); | ||
| 621 | return NULL; | ||
| 622 | } | ||
| 564 | data->type = PLIST_DATE; | 623 | data->type = PLIST_DATE; |
| 565 | data->realval = (double)sec + (double)usec / 1000000; | 624 | data->realval = (double)sec + (double)usec / 1000000; |
| 566 | data->length = sizeof(double); | 625 | data->length = sizeof(double); |
| @@ -570,6 +629,10 @@ plist_t plist_new_date(int32_t sec, int32_t usec) | |||
| 570 | plist_t plist_new_unix_date(int64_t sec) | 629 | plist_t plist_new_unix_date(int64_t sec) |
| 571 | { | 630 | { |
| 572 | plist_data_t data = plist_new_plist_data(); | 631 | plist_data_t data = plist_new_plist_data(); |
| 632 | if (!data) { | ||
| 633 | PLIST_ERR("%s: failed to allocate plist data\n", __func__); | ||
| 634 | return NULL; | ||
| 635 | } | ||
| 573 | data->type = PLIST_DATE; | 636 | data->type = PLIST_DATE; |
| 574 | data->realval = (double)sec - MAC_EPOCH; | 637 | data->realval = (double)sec - MAC_EPOCH; |
| 575 | data->length = sizeof(double); | 638 | data->length = sizeof(double); |
| @@ -579,6 +642,10 @@ plist_t plist_new_unix_date(int64_t sec) | |||
| 579 | plist_t plist_new_null(void) | 642 | plist_t plist_new_null(void) |
| 580 | { | 643 | { |
| 581 | plist_data_t data = plist_new_plist_data(); | 644 | plist_data_t data = plist_new_plist_data(); |
| 645 | if (!data) { | ||
| 646 | PLIST_ERR("%s: failed to allocate plist data\n", __func__); | ||
| 647 | return NULL; | ||
| 648 | } | ||
| 582 | data->type = PLIST_NULL; | 649 | data->type = PLIST_NULL; |
| 583 | data->intval = 0; | 650 | data->intval = 0; |
| 584 | data->length = 0; | 651 | data->length = 0; |
| @@ -1128,7 +1195,6 @@ plist_t plist_dict_get_item(plist_t node, const char* key) | |||
| 1128 | return NULL; | 1195 | return NULL; |
| 1129 | } | 1196 | } |
| 1130 | plist_data_t data = plist_get_data(node); | 1197 | plist_data_t data = plist_get_data(node); |
| 1131 | assert(data); | ||
| 1132 | if (!data) { | 1198 | if (!data) { |
| 1133 | PLIST_ERR("%s: invalid node\n", __func__); | 1199 | PLIST_ERR("%s: invalid node\n", __func__); |
| 1134 | return NULL; | 1200 | return NULL; |
| @@ -1187,7 +1253,10 @@ void plist_dict_set_item(plist_t node, const char* key, plist_t item) | |||
| 1187 | PLIST_ERR("%s: corrupt dict (value without key)\n", __func__); | 1253 | PLIST_ERR("%s: corrupt dict (value without key)\n", __func__); |
| 1188 | return; | 1254 | return; |
| 1189 | } | 1255 | } |
| 1190 | assert(PLIST_IS_KEY((plist_t)old_key)); | 1256 | if (!PLIST_IS_KEY((plist_t)old_key)) { |
| 1257 | PLIST_ERR("%s: corrupt dict ('key' node is not PLIST_KEY\n", __func__); | ||
| 1258 | return; | ||
| 1259 | } | ||
| 1191 | 1260 | ||
| 1192 | // detach old value (do NOT free yet) | 1261 | // detach old value (do NOT free yet) |
| 1193 | int idx = node_detach((node_t)node, old_val); | 1262 | int idx = node_detach((node_t)node, old_val); |
| @@ -1525,10 +1594,11 @@ static void plist_get_type_and_value(plist_t node, plist_type * type, void *valu | |||
| 1525 | { | 1594 | { |
| 1526 | plist_data_t data = NULL; | 1595 | plist_data_t data = NULL; |
| 1527 | 1596 | ||
| 1528 | if (!node) | 1597 | if (!node || !type || !value || !length) |
| 1529 | return; | 1598 | return; |
| 1530 | 1599 | ||
| 1531 | data = plist_get_data(node); | 1600 | data = plist_get_data(node); |
| 1601 | if (!data) return; | ||
| 1532 | 1602 | ||
| 1533 | *type = data->type; | 1603 | *type = data->type; |
| 1534 | *length = data->length; | 1604 | *length = data->length; |
| @@ -1549,9 +1619,17 @@ static void plist_get_type_and_value(plist_t node, plist_type * type, void *valu | |||
| 1549 | case PLIST_KEY: | 1619 | case PLIST_KEY: |
| 1550 | case PLIST_STRING: | 1620 | case PLIST_STRING: |
| 1551 | *((char **) value) = strdup(data->strval); | 1621 | *((char **) value) = strdup(data->strval); |
| 1622 | if (!*((char **) value)) { | ||
| 1623 | PLIST_ERR("%s: strdup failed\n", __func__); | ||
| 1624 | return; | ||
| 1625 | } | ||
| 1552 | break; | 1626 | break; |
| 1553 | case PLIST_DATA: | 1627 | case PLIST_DATA: |
| 1554 | *((uint8_t **) value) = (uint8_t *) malloc(*length * sizeof(uint8_t)); | 1628 | *((uint8_t **) value) = (uint8_t *) malloc(*length * sizeof(uint8_t)); |
| 1629 | if (!*((uint8_t **) value)) { | ||
| 1630 | PLIST_ERR("%s: malloc failed\n", __func__); | ||
| 1631 | return; | ||
| 1632 | } | ||
| 1555 | memcpy(*((uint8_t **) value), data->buff, *length * sizeof(uint8_t)); | 1633 | memcpy(*((uint8_t **) value), data->buff, *length * sizeof(uint8_t)); |
| 1556 | break; | 1634 | break; |
| 1557 | case PLIST_ARRAY: | 1635 | case PLIST_ARRAY: |
| @@ -1789,11 +1867,14 @@ char plist_compare_node_value(plist_t node_l, plist_t node_r) | |||
| 1789 | return plist_data_compare(node_l, node_r); | 1867 | return plist_data_compare(node_l, node_r); |
| 1790 | } | 1868 | } |
| 1791 | 1869 | ||
| 1792 | static void plist_set_element_val(plist_t node, plist_type type, const void *value, uint64_t length) | 1870 | static plist_err_t plist_set_element_val(plist_t node, plist_type type, const void *value, uint64_t length) |
| 1793 | { | 1871 | { |
| 1794 | //free previous allocated buffer | 1872 | //free previous allocated buffer |
| 1795 | plist_data_t data = plist_get_data(node); | 1873 | plist_data_t data = plist_get_data(node); |
| 1796 | assert(data); // a node should always have data attached | 1874 | if (!data) { // a node should always have data attached |
| 1875 | PLIST_ERR("%s: Failed to allocate plist data\n", __func__); | ||
| 1876 | return PLIST_ERR_NO_MEM; | ||
| 1877 | } | ||
| 1797 | 1878 | ||
| 1798 | switch (data->type) | 1879 | switch (data->type) |
| 1799 | { | 1880 | { |
| @@ -1831,9 +1912,17 @@ static void plist_set_element_val(plist_t node, plist_type type, const void *val | |||
| 1831 | case PLIST_KEY: | 1912 | case PLIST_KEY: |
| 1832 | case PLIST_STRING: | 1913 | case PLIST_STRING: |
| 1833 | data->strval = strdup((char *) value); | 1914 | data->strval = strdup((char *) value); |
| 1915 | if (!data->strval) { | ||
| 1916 | PLIST_ERR("%s: strdup failed\n", __func__); | ||
| 1917 | return PLIST_ERR_NO_MEM; | ||
| 1918 | } | ||
| 1834 | break; | 1919 | break; |
| 1835 | case PLIST_DATA: | 1920 | case PLIST_DATA: |
| 1836 | data->buff = (uint8_t *) malloc(length); | 1921 | data->buff = (uint8_t *) malloc(length); |
| 1922 | if (!data->buff) { | ||
| 1923 | PLIST_ERR("%s: malloc failed\n", __func__); | ||
| 1924 | return PLIST_ERR_NO_MEM; | ||
| 1925 | } | ||
| 1837 | memcpy(data->buff, value, length); | 1926 | memcpy(data->buff, value, length); |
| 1838 | break; | 1927 | break; |
| 1839 | case PLIST_ARRAY: | 1928 | case PLIST_ARRAY: |
| @@ -1841,6 +1930,7 @@ static void plist_set_element_val(plist_t node, plist_type type, const void *val | |||
| 1841 | default: | 1930 | default: |
| 1842 | break; | 1931 | break; |
| 1843 | } | 1932 | } |
| 1933 | return PLIST_ERR_SUCCESS; | ||
| 1844 | } | 1934 | } |
| 1845 | 1935 | ||
| 1846 | void plist_set_key_val(plist_t node, const char *val) | 1936 | void plist_set_key_val(plist_t node, const char *val) |
