Nikolay Sivov : msxml3: Add a helper for XMLHTTP response encoding detection.
Alexandre Julliard
julliard at winehq.org
Mon Aug 16 18:07:24 CDT 2021
Module: wine
Branch: master
Commit: c2b797cf658691bc65f8d2f28b2f926657922a6d
URL: https://source.winehq.org/git/wine.git/?a=commit;h=c2b797cf658691bc65f8d2f28b2f926657922a6d
Author: Nikolay Sivov <nsivov at codeweavers.com>
Date: Mon Aug 16 11:52:22 2021 +0300
msxml3: Add a helper for XMLHTTP response encoding detection.
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/msxml3/httprequest.c | 76 +++++++++++++++++++++++++++++++++++++++--------
1 file changed, 64 insertions(+), 12 deletions(-)
diff --git a/dlls/msxml3/httprequest.c b/dlls/msxml3/httprequest.c
index 7286eb97bb7..20ec389739e 100644
--- a/dlls/msxml3/httprequest.c
+++ b/dlls/msxml3/httprequest.c
@@ -1127,6 +1127,58 @@ static HRESULT httprequest_get_statusText(httprequest *This, BSTR *status)
return S_OK;
}
+enum response_encoding
+{
+ RESPONSE_ENCODING_NONE,
+ RESPONSE_ENCODING_UCS4BE,
+ RESPONSE_ENCODING_UCS4LE,
+ RESPONSE_ENCODING_UCS4_2143,
+ RESPONSE_ENCODING_UCS4_3412,
+ RESPONSE_ENCODING_EBCDIC,
+ RESPONSE_ENCODING_UTF8,
+ RESPONSE_ENCODING_UTF16LE,
+ RESPONSE_ENCODING_UTF16BE,
+};
+
+static unsigned int detect_response_encoding(const BYTE *in, unsigned int len)
+{
+ if (len >= 4)
+ {
+ if (in[0] == 0 && in[1] == 0 && in[2] == 0 && in[3] == 0x3c)
+ return RESPONSE_ENCODING_UCS4BE;
+ if (in[0] == 0x3c && in[1] == 0 && in[2] == 0 && in[3] == 0)
+ return RESPONSE_ENCODING_UCS4LE;
+ if (in[0] == 0 && in[1] == 0 && in[2] == 0x3c && in[3] == 0)
+ return RESPONSE_ENCODING_UCS4_2143;
+ if (in[0] == 0 && in[1] == 0x3c && in[2] == 0 && in[3] == 0)
+ return RESPONSE_ENCODING_UCS4_3412;
+ if (in[0] == 0x4c && in[1] == 0x6f && in[2] == 0xa7 && in[3] == 0x94)
+ return RESPONSE_ENCODING_EBCDIC;
+ if (in[0] == 0x3c && in[1] == 0x3f && in[2] == 0x78 && in[3] == 0x6d)
+ return RESPONSE_ENCODING_UTF8;
+ if (in[0] == 0x3c && in[1] == 0 && in[2] == 0x3f && in[3] == 0)
+ return RESPONSE_ENCODING_UTF16LE;
+ if (in[0] == 0 && in[1] == 0x3c && in[2] == 0 && in[3] == 0x3f)
+ return RESPONSE_ENCODING_UTF16BE;
+ }
+
+ if (len >= 3)
+ {
+ if (in[0] == 0xef && in[1] == 0xbb && in[2] == 0xbf)
+ return RESPONSE_ENCODING_UTF8;
+ }
+
+ if (len >= 2)
+ {
+ if (in[0] == 0xfe && in[1] == 0xff)
+ return RESPONSE_ENCODING_UTF16BE;
+ if (in[0] == 0xff && in[1] == 0xfe)
+ return RESPONSE_ENCODING_UTF16LE;
+ }
+
+ return RESPONSE_ENCODING_NONE;
+}
+
static HRESULT httprequest_get_responseText(httprequest *This, BSTR *body)
{
HGLOBAL hglobal;
@@ -1138,34 +1190,34 @@ static HRESULT httprequest_get_responseText(httprequest *This, BSTR *body)
hr = GetHGlobalFromStream(This->bsc->stream, &hglobal);
if (hr == S_OK)
{
- xmlChar *ptr = GlobalLock(hglobal);
+ const char *ptr = GlobalLock(hglobal);
DWORD size = GlobalSize(hglobal);
- xmlCharEncoding encoding = XML_CHAR_ENCODING_UTF8;
+ unsigned int encoding = RESPONSE_ENCODING_NONE;
/* try to determine data encoding */
if (size >= 4)
{
- encoding = xmlDetectCharEncoding(ptr, 4);
- TRACE("detected encoding: %s\n", debugstr_a(xmlGetCharEncodingName(encoding)));
- if ( encoding != XML_CHAR_ENCODING_UTF8 &&
- encoding != XML_CHAR_ENCODING_UTF16LE &&
- encoding != XML_CHAR_ENCODING_NONE )
+ encoding = detect_response_encoding((const BYTE *)ptr, 4);
+ TRACE("detected encoding: %u.\n", encoding);
+
+ if (encoding != RESPONSE_ENCODING_UTF8 &&
+ encoding != RESPONSE_ENCODING_UTF16LE &&
+ encoding != RESPONSE_ENCODING_NONE )
{
- FIXME("unsupported encoding: %s\n", debugstr_a(xmlGetCharEncodingName(encoding)));
+ FIXME("unsupported response encoding: %u.\n", encoding);
GlobalUnlock(hglobal);
return E_FAIL;
}
}
/* without BOM assume UTF-8 */
- if (encoding == XML_CHAR_ENCODING_UTF8 ||
- encoding == XML_CHAR_ENCODING_NONE )
+ if (encoding == RESPONSE_ENCODING_UTF8 || encoding == RESPONSE_ENCODING_NONE)
{
- DWORD length = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)ptr, size, NULL, 0);
+ DWORD length = MultiByteToWideChar(CP_UTF8, 0, ptr, size, NULL, 0);
*body = SysAllocStringLen(NULL, length);
if (*body)
- MultiByteToWideChar( CP_UTF8, 0, (LPCSTR)ptr, size, *body, length);
+ MultiByteToWideChar( CP_UTF8, 0, ptr, size, *body, length);
}
else
*body = SysAllocStringByteLen((LPCSTR)ptr, size);
More information about the wine-cvs
mailing list