From 673800fe903588164b703e0e9be04ced78492b93 Mon Sep 17 00:00:00 2001 From: Eion Robb Date: Sun, 19 Feb 2017 03:13:47 +0000 Subject: [PATCH 1/2] Fix for crash when sending invalid xml entities separated by whitespace, eg "&# 3000;" --HG-- branch : EionRobb/fix-for-crash-when-sending-invalid-xml-e-1487474010880 --- libpurple/util.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libpurple/util.c b/libpurple/util.c index 9f2a904ae688..4b8fecd2ab84 100644 --- a/libpurple/util.c +++ b/libpurple/util.c @@ -978,8 +978,8 @@ purple_markup_unescape_entity(const char *text, int *length) else if(IS_ENTITY("'")) pln = "\'"; else if(*(text+1) == '#' && - (sscanf(text, "&#%u%1[;]", £, temp) == 2 || - sscanf(text, "&#x%x%1[;]", £, temp) == 2) && + (sscanf(text, "&#%*[^ ]%u%1[;]", £, temp) == 2 || + sscanf(text, "&#x%*[^ ]%x%1[;]", £, temp) == 2) && pound != 0) { static char buf[7]; int buflen = g_unichar_to_utf8((gunichar)pound, buf); -- 2.9.3 From 4a5ebea2ad6281bd7a223d33fac3dcd2fe5cd798 Mon Sep 17 00:00:00 2001 From: Eion Robb Date: Mon, 20 Feb 2017 21:05:32 +0000 Subject: [PATCH 2/2] Use the more robust entity processing that @dequisdequis came up with --HG-- branch : EionRobb/fix-for-crash-when-sending-invalid-xml-e-1487474010880 --- libpurple/util.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/libpurple/util.c b/libpurple/util.c index 4b8fecd2ab84..cff526de0726 100644 --- a/libpurple/util.c +++ b/libpurple/util.c @@ -977,18 +977,29 @@ purple_markup_unescape_entity(const char *text, int *length) pln = "\302\256"; /* or use g_unichar_to_utf8(0xae); */ else if(IS_ENTITY("'")) pln = "\'"; - else if(*(text+1) == '#' && - (sscanf(text, "&#%*[^ ]%u%1[;]", £, temp) == 2 || - sscanf(text, "&#x%*[^ ]%x%1[;]", £, temp) == 2) && - pound != 0) { + else if(text[1] == '#' && g_ascii_isxdigit(text[2])) { static char buf[7]; - int buflen = g_unichar_to_utf8((gunichar)pound, buf); + const char *start = text + 2; + char *end; + guint64 pound; + int base = 10; + int buflen; + + if (*start == 'x') { + base = 16; + start++; + } + + pound = g_ascii_strtoull(start, &end, base); + if (pound == 0 || pound > INT_MAX || *end != ';') { + return NULL; + } + + len = (end - text) + 1; + + buflen = g_unichar_to_utf8((gunichar)pound, buf); buf[buflen] = '\0'; pln = buf; - - len = (*(text+2) == 'x' ? 3 : 2); - while(isxdigit((gint) text[len])) len++; - if(text[len] == ';') len++; } else return NULL; -- 2.9.3