diff --git a/dlls/webservices/reader.c b/dlls/webservices/reader.c
index 655288a5ab7..de926033369 100644
--- a/dlls/webservices/reader.c
+++ b/dlls/webservices/reader.c
@@ -1249,23 +1249,45 @@ static HRESULT decode_text( const unsigned char *str, ULONG len, unsigned char *
int len_utf8, cp = 0;
p++; len--;
- if (!len || *p != 'x') return WS_E_INVALID_FORMAT;
- p++; len--;
-
- start = len;
- while (len && isxdigit( *p )) { p++; len--; };
if (!len) return WS_E_INVALID_FORMAT;
-
- p -= nb_digits = start - len;
- if (!nb_digits || nb_digits > 5 || p[nb_digits] != ';') return WS_E_INVALID_FORMAT;
- for (i = 0; i < nb_digits; i++)
+ else if (*p == 'x')
{
- cp *= 16;
- if (*p >= '0' && *p <= '9') cp += *p - '0';
- else if (*p >= 'a' && *p <= 'f') cp += *p - 'a' + 10;
- else cp += *p - 'A' + 10;
- p++;
+ p++; len--;
+
+ start = len;
+ while (len && isxdigit( *p )) { p++; len--; };
+ if (!len) return WS_E_INVALID_FORMAT;
+
+ p -= nb_digits = start - len;
+ if (!nb_digits || nb_digits > 5 || p[nb_digits] != ';') return WS_E_INVALID_FORMAT;
+ for (i = 0; i < nb_digits; i++)
+ {
+ cp *= 16;
+ if (*p >= '0' && *p <= '9') cp += *p - '0';
+ else if (*p >= 'a' && *p <= 'f') cp += *p - 'a' + 10;
+ else cp += *p - 'A' + 10;
+ p++;
+ }
}
+ else if (isdigit( *p ))
+ {
+ while (len && *p == '0') { p++; len--; };
+ if (!len) return WS_E_INVALID_FORMAT;
+
+ start = len;
+ while (len && isdigit( *p )) { p++; len--; };
+ if (!len) return WS_E_INVALID_FORMAT;
+
+ p -= nb_digits = start - len;
+ if (!nb_digits || nb_digits > 7 || p[nb_digits] != ';') return WS_E_INVALID_FORMAT;
+ for (i = 0; i < nb_digits; i++)
+ {
+ cp *= 10;
+ cp += *p - '0';
+ p++;
+ }
+ }
+ else return WS_E_INVALID_FORMAT;
p++; len--;
if ((len_utf8 = codepoint_to_utf8( cp, q )) < 0) return WS_E_INVALID_FORMAT;
*ret_len += len_utf8;
diff --git a/dlls/webservices/tests/reader.c b/dlls/webservices/tests/reader.c
index 76de14a3447..f0fe729c643 100644
--- a/dlls/webservices/tests/reader.c
+++ b/dlls/webservices/tests/reader.c
@@ -3611,10 +3611,14 @@ static void test_entities(void)
static const char str26[] = "";
static const char str27[] = "<";
static const char str28[] = "";
+ static const char str29[] = "";
+ static const char str30[] = "A";
+ static const char str31[] = "ア";
static const char res4[] = {0xea, 0xaa, 0xaa, 0x00};
static const char res5[] = {0xf2, 0xaa, 0xaa, 0xaa, 0x00};
static const char res21[] = {0xed, 0x9f, 0xbf, 0x00};
static const char res24[] = {0xee, 0x80, 0x80, 0x00};
+ static const char res31[] = {0xef, 0xbd, 0xb1, 0x00};
static const struct
{
const char *str;
@@ -3651,6 +3655,9 @@ static void test_entities(void)
{ str26, WS_E_INVALID_FORMAT },
{ str27, WS_E_INVALID_FORMAT },
{ str28, WS_E_INVALID_FORMAT },
+ { str29, WS_E_INVALID_FORMAT },
+ { str30, S_OK, "A" },
+ { str31, S_OK, res31 },
};
HRESULT hr;
WS_XML_READER *reader;