summaryrefslogtreecommitdiffstats
path: root/src/jplist.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/jplist.c')
-rw-r--r--src/jplist.c48
1 files changed, 38 insertions, 10 deletions
diff --git a/src/jplist.c b/src/jplist.c
index 2e53400..9a40844 100644
--- a/src/jplist.c
+++ b/src/jplist.c
@@ -323,6 +323,11 @@ static plist_err_t _node_estimate_size(node_t node, uint64_t *size, uint32_t dep
323 return PLIST_ERR_INVALID_ARG; 323 return PLIST_ERR_INVALID_ARG;
324 } 324 }
325 325
326 if (depth > PLIST_MAX_NESTING_DEPTH) {
327 PLIST_JSON_WRITE_ERR("maximum nesting depth (%u) exceeded\n", (unsigned)PLIST_MAX_NESTING_DEPTH);
328 return PLIST_ERR_MAX_NESTING;
329 }
330
326 if (hash_table_lookup(visited, node)) { 331 if (hash_table_lookup(visited, node)) {
327 PLIST_JSON_WRITE_ERR("circular reference detected\n"); 332 PLIST_JSON_WRITE_ERR("circular reference detected\n");
328 return PLIST_ERR_CIRCULAR_REF; 333 return PLIST_ERR_CIRCULAR_REF;
@@ -471,6 +476,7 @@ plist_err_t plist_to_json(plist_t plist, char **plist_json, uint32_t* length, in
471typedef struct { 476typedef struct {
472 jsmntok_t* tokens; 477 jsmntok_t* tokens;
473 int count; 478 int count;
479 plist_err_t err;
474} jsmntok_info_t; 480} jsmntok_info_t;
475 481
476static int64_t parse_decimal(const char* str, const char* str_end, char** endp) 482static int64_t parse_decimal(const char* str, const char* str_end, char** endp)
@@ -698,12 +704,18 @@ static plist_t parse_string(const char* js, jsmntok_info_t* ti, int* index)
698 return node; 704 return node;
699} 705}
700 706
701static plist_t parse_object(const char* js, jsmntok_info_t* ti, int* index); 707static plist_t parse_object(const char* js, jsmntok_info_t* ti, int* index, uint32_t depth);
702 708
703static plist_t parse_array(const char* js, jsmntok_info_t* ti, int* index) 709static plist_t parse_array(const char* js, jsmntok_info_t* ti, int* index, uint32_t depth)
704{ 710{
705 if (ti->tokens[*index].type != JSMN_ARRAY) { 711 if (ti->tokens[*index].type != JSMN_ARRAY) {
706 PLIST_JSON_ERR("%s: token type != JSMN_ARRAY\n", __func__); 712 PLIST_JSON_ERR("%s: token type != JSMN_ARRAY\n", __func__);
713 ti->err = PLIST_ERR_PARSE;
714 return NULL;
715 }
716 if (depth > PLIST_MAX_NESTING_DEPTH) {
717 PLIST_JSON_ERR("%s: maximum nesting depth (%u) exceeded\n", __func__, (unsigned)PLIST_MAX_NESTING_DEPTH);
718 ti->err = PLIST_ERR_MAX_NESTING;
707 return NULL; 719 return NULL;
708 } 720 }
709 plist_t arr = plist_new_array(); 721 plist_t arr = plist_new_array();
@@ -714,15 +726,16 @@ static plist_t parse_array(const char* js, jsmntok_info_t* ti, int* index)
714 if (j >= ti->count) { 726 if (j >= ti->count) {
715 PLIST_JSON_ERR("%s: token index out of valid range\n", __func__); 727 PLIST_JSON_ERR("%s: token index out of valid range\n", __func__);
716 plist_free(arr); 728 plist_free(arr);
729 ti->err = PLIST_ERR_PARSE;
717 return NULL; 730 return NULL;
718 } 731 }
719 plist_t val = NULL; 732 plist_t val = NULL;
720 switch (ti->tokens[j].type) { 733 switch (ti->tokens[j].type) {
721 case JSMN_OBJECT: 734 case JSMN_OBJECT:
722 val = parse_object(js, ti, &j); 735 val = parse_object(js, ti, &j, depth+1);
723 break; 736 break;
724 case JSMN_ARRAY: 737 case JSMN_ARRAY:
725 val = parse_array(js, ti, &j); 738 val = parse_array(js, ti, &j, depth+1);
726 break; 739 break;
727 case JSMN_STRING: 740 case JSMN_STRING:
728 val = parse_string(js, ti, &j); 741 val = parse_string(js, ti, &j);
@@ -737,6 +750,7 @@ static plist_t parse_array(const char* js, jsmntok_info_t* ti, int* index)
737 plist_array_append_item(arr, val); 750 plist_array_append_item(arr, val);
738 } else { 751 } else {
739 plist_free(arr); 752 plist_free(arr);
753 ti->err = PLIST_ERR_PARSE;
740 return NULL; 754 return NULL;
741 } 755 }
742 } 756 }
@@ -744,10 +758,16 @@ static plist_t parse_array(const char* js, jsmntok_info_t* ti, int* index)
744 return arr; 758 return arr;
745} 759}
746 760
747static plist_t parse_object(const char* js, jsmntok_info_t* ti, int* index) 761static plist_t parse_object(const char* js, jsmntok_info_t* ti, int* index, uint32_t depth)
748{ 762{
749 if (ti->tokens[*index].type != JSMN_OBJECT) { 763 if (ti->tokens[*index].type != JSMN_OBJECT) {
750 PLIST_JSON_ERR("%s: token type != JSMN_OBJECT\n", __func__); 764 PLIST_JSON_ERR("%s: token type != JSMN_OBJECT\n", __func__);
765 ti->err = PLIST_ERR_PARSE;
766 return NULL;
767 }
768 if (depth > PLIST_MAX_NESTING_DEPTH) {
769 PLIST_JSON_ERR("%s: maximum nesting depth (%u) exceeded\n", __func__, (unsigned)PLIST_MAX_NESTING_DEPTH);
770 ti->err = PLIST_ERR_MAX_NESTING;
751 return NULL; 771 return NULL;
752 } 772 }
753 int num_tokens = ti->tokens[*index].size; 773 int num_tokens = ti->tokens[*index].size;
@@ -755,6 +775,7 @@ static plist_t parse_object(const char* js, jsmntok_info_t* ti, int* index)
755 int j = (*index)+1; 775 int j = (*index)+1;
756 if (num_tokens % 2 != 0) { 776 if (num_tokens % 2 != 0) {
757 PLIST_JSON_ERR("%s: number of children must be even\n", __func__); 777 PLIST_JSON_ERR("%s: number of children must be even\n", __func__);
778 ti->err = PLIST_ERR_PARSE;
758 return NULL; 779 return NULL;
759 } 780 }
760 plist_t obj = plist_new_dict(); 781 plist_t obj = plist_new_dict();
@@ -762,12 +783,14 @@ static plist_t parse_object(const char* js, jsmntok_info_t* ti, int* index)
762 if (j+1 >= ti->count) { 783 if (j+1 >= ti->count) {
763 PLIST_JSON_ERR("%s: token index out of valid range\n", __func__); 784 PLIST_JSON_ERR("%s: token index out of valid range\n", __func__);
764 plist_free(obj); 785 plist_free(obj);
786 ti->err = PLIST_ERR_PARSE;
765 return NULL; 787 return NULL;
766 } 788 }
767 if (ti->tokens[j].type == JSMN_STRING) { 789 if (ti->tokens[j].type == JSMN_STRING) {
768 char* key = unescape_string(js + ti->tokens[j].start, ti->tokens[j].end - ti->tokens[j].start, NULL); 790 char* key = unescape_string(js + ti->tokens[j].start, ti->tokens[j].end - ti->tokens[j].start, NULL);
769 if (!key) { 791 if (!key) {
770 plist_free(obj); 792 plist_free(obj);
793 ti->err = PLIST_ERR_PARSE;
771 return NULL; 794 return NULL;
772 } 795 }
773 plist_t val = NULL; 796 plist_t val = NULL;
@@ -775,10 +798,10 @@ static plist_t parse_object(const char* js, jsmntok_info_t* ti, int* index)
775 num++; 798 num++;
776 switch (ti->tokens[j].type) { 799 switch (ti->tokens[j].type) {
777 case JSMN_OBJECT: 800 case JSMN_OBJECT:
778 val = parse_object(js, ti, &j); 801 val = parse_object(js, ti, &j, depth+1);
779 break; 802 break;
780 case JSMN_ARRAY: 803 case JSMN_ARRAY:
781 val = parse_array(js, ti, &j); 804 val = parse_array(js, ti, &j, depth+1);
782 break; 805 break;
783 case JSMN_STRING: 806 case JSMN_STRING:
784 val = parse_string(js, ti, &j); 807 val = parse_string(js, ti, &j);
@@ -794,12 +817,14 @@ static plist_t parse_object(const char* js, jsmntok_info_t* ti, int* index)
794 } else { 817 } else {
795 free(key); 818 free(key);
796 plist_free(obj); 819 plist_free(obj);
820 ti->err = PLIST_ERR_PARSE;
797 return NULL; 821 return NULL;
798 } 822 }
799 free(key); 823 free(key);
800 } else { 824 } else {
801 PLIST_JSON_ERR("%s: keys must be of type STRING\n", __func__); 825 PLIST_JSON_ERR("%s: keys must be of type STRING\n", __func__);
802 plist_free(obj); 826 plist_free(obj);
827 ti->err = PLIST_ERR_PARSE;
803 return NULL; 828 return NULL;
804 } 829 }
805 } 830 }
@@ -859,7 +884,7 @@ plist_err_t plist_from_json(const char *json, uint32_t length, plist_t * plist)
859 } 884 }
860 885
861 int startindex = 0; 886 int startindex = 0;
862 jsmntok_info_t ti = { tokens, parser.toknext }; 887 jsmntok_info_t ti = { tokens, parser.toknext, PLIST_ERR_SUCCESS };
863 switch (tokens[startindex].type) { 888 switch (tokens[startindex].type) {
864 case JSMN_PRIMITIVE: 889 case JSMN_PRIMITIVE:
865 *plist = parse_primitive(json, &ti, &startindex); 890 *plist = parse_primitive(json, &ti, &startindex);
@@ -868,14 +893,17 @@ plist_err_t plist_from_json(const char *json, uint32_t length, plist_t * plist)
868 *plist = parse_string(json, &ti, &startindex); 893 *plist = parse_string(json, &ti, &startindex);
869 break; 894 break;
870 case JSMN_ARRAY: 895 case JSMN_ARRAY:
871 *plist = parse_array(json, &ti, &startindex); 896 *plist = parse_array(json, &ti, &startindex, 0);
872 break; 897 break;
873 case JSMN_OBJECT: 898 case JSMN_OBJECT:
874 *plist = parse_object(json, &ti, &startindex); 899 *plist = parse_object(json, &ti, &startindex, 0);
875 break; 900 break;
876 default: 901 default:
877 break; 902 break;
878 } 903 }
879 free(tokens); 904 free(tokens);
905 if (!*plist) {
906 return (ti.err != PLIST_ERR_SUCCESS) ? ti.err : PLIST_ERR_PARSE;
907 }
880 return PLIST_ERR_SUCCESS; 908 return PLIST_ERR_SUCCESS;
881} 909}