summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/xplist.c54
1 files changed, 51 insertions, 3 deletions
diff --git a/src/xplist.c b/src/xplist.c
index 91b4645..e4eb56a 100644
--- a/src/xplist.c
+++ b/src/xplist.c
@@ -518,7 +518,7 @@ static char* get_text_content(parse_ctx ctx, const char* tag, int skip_ws, int u
518 if (i >= len) { 518 if (i >= len) {
519 break; 519 break;
520 } 520 }
521 if (str+i > entp+1) { 521 if (str+i >= entp+1) {
522 int entlen = str+i - entp; 522 int entlen = str+i - entp;
523 if (!strncmp(entp, "amp", 3)) { 523 if (!strncmp(entp, "amp", 3)) {
524 /* the '&' is already there */ 524 /* the '&' is already there */
@@ -530,9 +530,57 @@ static char* get_text_content(parse_ctx ctx, const char* tag, int skip_ws, int u
530 *(entp-1) = '<'; 530 *(entp-1) = '<';
531 } else if (!strncmp(entp, "gt", 2)) { 531 } else if (!strncmp(entp, "gt", 2)) {
532 *(entp-1) = '>'; 532 *(entp-1) = '>';
533 } else if (*entp == '#') {
534 /* numerical character reference */
535 uint64_t val = 0;
536 char* ep = NULL;
537 if (entlen > 8) {
538 PLIST_XML_ERR("Invalid numerical character reference encountered, sequence too long: &%.*s;\n", entlen, entp);
539 return NULL;
540 }
541 if (*(entp+1) == 'x' || *(entp+1) == 'X') {
542 if (entlen < 3) {
543 PLIST_XML_ERR("Invalid numerical character reference encountered, sequence too short: &%.*s;\n", entlen, entp);
544 return NULL;
545 }
546 val = strtoull(entp+2, &ep, 16);
547 } else {
548 if (entlen < 2) {
549 PLIST_XML_ERR("Invalid numerical character reference encountered, sequence too short: &%.*s;\n", entlen, entp);
550 return NULL;
551 }
552 val = strtoull(entp+1, &ep, 10);
553 }
554 if (val == 0 || val > 0x10FFFF || ep-entp != entlen) {
555 PLIST_XML_ERR("Invalid numerical character reference found: &%.*s;\n", entlen, entp);
556 return NULL;
557 }
558 /* convert to UTF8 */
559 if (val >= 0x10000) {
560 /* four bytes */
561 *(entp-1) = (char)(0xF0 + ((val >> 18) & 0x7));
562 *(entp+0) = (char)(0x80 + ((val >> 12) & 0x3F));
563 *(entp+1) = (char)(0x80 + ((val >> 6) & 0x3F));
564 *(entp+2) = (char)(0x80 + (val & 0x3F));
565 entp+=3;
566 } else if (val >= 0x800) {
567 /* three bytes */
568 *(entp-1) = (char)(0xE0 + ((val >> 12) & 0xF));
569 *(entp+0) = (char)(0x80 + ((val >> 6) & 0x3F));
570 *(entp+1) = (char)(0x80 + (val & 0x3F));
571 entp+=2;
572 } else if (val >= 0x80) {
573 /* two bytes */
574 *(entp-1) = (char)(0xC0 + ((val >> 6) & 0x1F));
575 *(entp+0) = (char)(0x80 + (val & 0x3F));
576 entp++;
577 } else {
578 /* one byte */
579 *(entp-1) = (char)(val & 0x7F);
580 }
533 } else { 581 } else {
534 /* unexpected entity, replace with ? */ 582 PLIST_XML_ERR("Invalid entity encountered: &%.*s;\n", entlen, entp);
535 *(entp-1) = '?'; 583 return NULL;
536 } 584 }
537 memmove(entp, str+i+1, len - i); 585 memmove(entp, str+i+1, len - i);
538 i -= entlen; 586 i -= entlen;