summaryrefslogtreecommitdiffstats
path: root/src/xplist.c
diff options
context:
space:
mode:
authorGravatar Nikias Bassen2017-02-07 02:11:12 +0100
committerGravatar Nikias Bassen2017-02-07 02:11:12 +0100
commitcf9ee441ae0ef0dff4f16c3a7f5652ed113ff7bc (patch)
treeb3c55ff55559673161564e71c1709ab7672adec8 /src/xplist.c
parent35fdf8e73b9ee75b880cb9ff2de5491d7ddae20b (diff)
downloadlibplist-cf9ee441ae0ef0dff4f16c3a7f5652ed113ff7bc.tar.gz
libplist-cf9ee441ae0ef0dff4f16c3a7f5652ed113ff7bc.tar.bz2
xplist: Catch some more error conditions
Diffstat (limited to 'src/xplist.c')
-rw-r--r--src/xplist.c71
1 files changed, 37 insertions, 34 deletions
diff --git a/src/xplist.c b/src/xplist.c
index 19fbdbd..0e8b7e6 100644
--- a/src/xplist.c
+++ b/src/xplist.c
@@ -787,7 +787,9 @@ static char* text_parts_get_content(text_part_t *tp, int unesc_entities, size_t
787 787
788static void node_from_xml(parse_ctx ctx, plist_t *plist, uint32_t depth) 788static void node_from_xml(parse_ctx ctx, plist_t *plist, uint32_t depth)
789{ 789{
790 char *tag = NULL;
790 char *keyname = NULL; 791 char *keyname = NULL;
792 plist_t subnode = NULL;
791 const char *p = NULL; 793 const char *p = NULL;
792 while (ctx->pos < ctx->end && !ctx->err) { 794 while (ctx->pos < ctx->end && !ctx->err) {
793 parse_skip_ws(ctx); 795 parse_skip_ws(ctx);
@@ -798,24 +800,27 @@ static void node_from_xml(parse_ctx ctx, plist_t *plist, uint32_t depth)
798 p = ctx->pos; 800 p = ctx->pos;
799 find_next(ctx, " \t\r\n", 4, 0); 801 find_next(ctx, " \t\r\n", 4, 0);
800 PLIST_XML_ERR("Expected: opening tag, found: %.*s\n", (int)(ctx->pos - p), p); 802 PLIST_XML_ERR("Expected: opening tag, found: %.*s\n", (int)(ctx->pos - p), p);
801 ctx->pos = ctx->end;
802 ctx->err++; 803 ctx->err++;
803 break; 804 goto err_out;
804 } 805 }
805 ctx->pos++; 806 ctx->pos++;
806 if (ctx->pos >= ctx->end) { 807 if (ctx->pos >= ctx->end) {
807 break; 808 PLIST_XML_ERR("EOF while parsing tag\n");
809 ctx->err++;
810 goto err_out;
808 } 811 }
809 812
810 if (*(ctx->pos) == '?') { 813 if (*(ctx->pos) == '?') {
811 find_str(ctx, "?>", 2, 1); 814 find_str(ctx, "?>", 2, 1);
812 if (ctx->pos >= ctx->end) { 815 if (ctx->pos >= ctx->end-2) {
813 break; 816 PLIST_XML_ERR("EOF while looking for <? tag closing marker\n");
817 ctx->err++;
818 goto err_out;
814 } 819 }
815 if (strncmp(ctx->pos, "?>", 2)) { 820 if (strncmp(ctx->pos, "?>", 2)) {
816 PLIST_XML_ERR("Couldn't find <? tag closing marker\n"); 821 PLIST_XML_ERR("Couldn't find <? tag closing marker\n");
817 ctx->pos = ctx->end; 822 ctx->err++;
818 return; 823 goto err_out;
819 } 824 }
820 ctx->pos += 2; 825 ctx->pos += 2;
821 continue; 826 continue;
@@ -826,8 +831,8 @@ static void node_from_xml(parse_ctx ctx, plist_t *plist, uint32_t depth)
826 find_str(ctx,"-->", 3, 0); 831 find_str(ctx,"-->", 3, 0);
827 if (strncmp(ctx->pos, "-->", 3)) { 832 if (strncmp(ctx->pos, "-->", 3)) {
828 PLIST_XML_ERR("Couldn't find end of comment\n"); 833 PLIST_XML_ERR("Couldn't find end of comment\n");
829 ctx->pos = ctx->end; 834 ctx->err++;
830 return; 835 goto err_out;
831 } 836 }
832 ctx->pos+=3; 837 ctx->pos+=3;
833 } else if (((ctx->end - ctx->pos) > 8) && !strncmp(ctx->pos, "!DOCTYPE", 8)) { 838 } else if (((ctx->end - ctx->pos) > 8) && !strncmp(ctx->pos, "!DOCTYPE", 8)) {
@@ -850,16 +855,17 @@ static void node_from_xml(parse_ctx ctx, plist_t *plist, uint32_t depth)
850 find_str(ctx, "]>", 2, 1); 855 find_str(ctx, "]>", 2, 1);
851 if (strncmp(ctx->pos, "]>", 2)) { 856 if (strncmp(ctx->pos, "]>", 2)) {
852 PLIST_XML_ERR("Couldn't find end of DOCTYPE\n"); 857 PLIST_XML_ERR("Couldn't find end of DOCTYPE\n");
853 ctx->pos = ctx->end; 858 ctx->err++;
854 return; 859 goto err_out;
855 } 860 }
856 ctx->pos += 2; 861 ctx->pos += 2;
857 } 862 }
858 } else { 863 } else {
859 p = ctx->pos; 864 p = ctx->pos;
860 find_next(ctx, " \r\n\t>", 5, 1); 865 find_next(ctx, " \r\n\t>", 5, 1);
861 PLIST_XML_ERR("Invalid special tag <%.*s> encountered\n", (int)(ctx->pos - p), p); 866 PLIST_XML_ERR("Invalid or incomplete special tag <%.*s> encountered\n", (int)(ctx->pos - p), p);
862 ctx->err++; 867 ctx->err++;
868 goto err_out;
863 } 869 }
864 continue; 870 continue;
865 } else { 871 } else {
@@ -869,13 +875,11 @@ static void node_from_xml(parse_ctx ctx, plist_t *plist, uint32_t depth)
869 find_next(ctx," \r\n\t<>", 6, 0); 875 find_next(ctx," \r\n\t<>", 6, 0);
870 if (ctx->pos >= ctx->end) { 876 if (ctx->pos >= ctx->end) {
871 PLIST_XML_ERR("Unexpected EOF while parsing XML\n"); 877 PLIST_XML_ERR("Unexpected EOF while parsing XML\n");
872 ctx->pos = ctx->end;
873 ctx->err++; 878 ctx->err++;
874 free(keyname); 879 goto err_out;
875 return;
876 } 880 }
877 int taglen = ctx->pos - p; 881 int taglen = ctx->pos - p;
878 char *tag = malloc(taglen + 1); 882 tag = malloc(taglen + 1);
879 strncpy(tag, p, taglen); 883 strncpy(tag, p, taglen);
880 tag[taglen] = '\0'; 884 tag[taglen] = '\0';
881 if (*ctx->pos != '>') { 885 if (*ctx->pos != '>') {
@@ -883,19 +887,13 @@ static void node_from_xml(parse_ctx ctx, plist_t *plist, uint32_t depth)
883 } 887 }
884 if (ctx->pos >= ctx->end) { 888 if (ctx->pos >= ctx->end) {
885 PLIST_XML_ERR("Unexpected EOF while parsing XML\n"); 889 PLIST_XML_ERR("Unexpected EOF while parsing XML\n");
886 ctx->pos = ctx->end;
887 ctx->err++; 890 ctx->err++;
888 free(tag); 891 goto err_out;
889 free(keyname);
890 return;
891 } 892 }
892 if (*ctx->pos != '>') { 893 if (*ctx->pos != '>') {
893 PLIST_XML_ERR("Missing '>' for tag <%s\n", tag); 894 PLIST_XML_ERR("Missing '>' for tag <%s\n", tag);
894 ctx->pos = ctx->end;
895 ctx->err++; 895 ctx->err++;
896 free(tag); 896 goto err_out;
897 free(keyname);
898 return;
899 } 897 }
900 if (*(ctx->pos-1) == '/') { 898 if (*(ctx->pos-1) == '/') {
901 int idx = ctx->pos - p - 1; 899 int idx = ctx->pos - p - 1;
@@ -906,9 +904,10 @@ static void node_from_xml(parse_ctx ctx, plist_t *plist, uint32_t depth)
906 ctx->pos++; 904 ctx->pos++;
907 if (!strcmp(tag, "plist")) { 905 if (!strcmp(tag, "plist")) {
908 free(tag); 906 free(tag);
907 tag = NULL;
909 if (is_empty) { 908 if (is_empty) {
910 PLIST_XML_ERR("Empty plist tag\n"); 909 PLIST_XML_ERR("Empty plist tag\n");
911 return; 910 break;
912 } 911 }
913 if (!*plist) { 912 if (!*plist) {
914 /* only process first plist node found */ 913 /* only process first plist node found */
@@ -919,19 +918,15 @@ static void node_from_xml(parse_ctx ctx, plist_t *plist, uint32_t depth)
919 if (!*plist) { 918 if (!*plist) {
920 PLIST_XML_ERR("Empty plist tag\n"); 919 PLIST_XML_ERR("Empty plist tag\n");
921 } 920 }
922 free(tag); 921 goto err_out;
923 free(keyname);
924 return;
925 } else if (depth == 1 && *plist) { 922 } else if (depth == 1 && *plist) {
926 PLIST_XML_ERR("Unexpected tag <%s> found while </plist> is expected\n", tag); 923 PLIST_XML_ERR("Unexpected tag <%s> found while </plist> is expected\n", tag);
927 ctx->err++; 924 ctx->err++;
928 free(tag); 925 goto err_out;
929 free(keyname);
930 return;
931 } 926 }
932 927
933 plist_data_t data = plist_new_plist_data(); 928 plist_data_t data = plist_new_plist_data();
934 plist_t subnode = plist_new_node(data); 929 subnode = plist_new_node(data);
935 930
936 if (!strcmp(tag, XPLIST_DICT)) { 931 if (!strcmp(tag, XPLIST_DICT)) {
937 data->type = PLIST_DICT; 932 data->type = PLIST_DICT;
@@ -1052,6 +1047,7 @@ static void node_from_xml(parse_ctx ctx, plist_t *plist, uint32_t depth)
1052 if (!strcmp(tag, "key") && !keyname && *plist && (plist_get_node_type(*plist) == PLIST_DICT)) { 1047 if (!strcmp(tag, "key") && !keyname && *plist && (plist_get_node_type(*plist) == PLIST_DICT)) {
1053 keyname = str; 1048 keyname = str;
1054 free(tag); 1049 free(tag);
1050 tag = NULL;
1055 plist_free(subnode); 1051 plist_free(subnode);
1056 subnode = NULL; 1052 subnode = NULL;
1057 continue; 1053 continue;
@@ -1220,21 +1216,28 @@ static void node_from_xml(parse_ctx ctx, plist_t *plist, uint32_t depth)
1220 break; 1216 break;
1221 } 1217 }
1222 } 1218 }
1223err_out:
1224 free(tag); 1219 free(tag);
1220 tag = NULL;
1225 free(keyname); 1221 free(keyname);
1226 keyname = NULL; 1222 keyname = NULL;
1227 plist_free(subnode); 1223 plist_free(subnode);
1228 subnode = NULL; 1224 subnode = NULL;
1229 if (closing_tag || ctx->err) { 1225 if (closing_tag) {
1230 break; 1226 break;
1231 } 1227 }
1232 } 1228 }
1233 } 1229 }
1230
1234 if (depth == 1) { 1231 if (depth == 1) {
1235 PLIST_XML_ERR("EOF while </plist> tag is expected\n"); 1232 PLIST_XML_ERR("EOF while </plist> tag is expected\n");
1236 ctx->err++; 1233 ctx->err++;
1237 } 1234 }
1235
1236err_out:
1237 free(tag);
1238 free(keyname);
1239 plist_free(subnode);
1240
1238 if (ctx->err) { 1241 if (ctx->err) {
1239 plist_free(*plist); 1242 plist_free(*plist);
1240 *plist = NULL; 1243 *plist = NULL;