[PATCH 7/8] mshtml: Check for valid XML Content-Type for responseXML in IE10+ modes.

Gabriel Ivăncescu gabrielopcode at gmail.com
Mon Jun 6 07:24:15 CDT 2022


For some reason, Gecko returns an XML document here, but native follows
the spec.

Signed-off-by: Gabriel Ivăncescu <gabrielopcode at gmail.com>
---
 dlls/mshtml/tests/script.c   | 10 ++++++-
 dlls/mshtml/tests/xhr.js     | 57 ++++++++++++++++++++++++++++++++++--
 dlls/mshtml/xmlhttprequest.c | 29 ++++++++++++++++++
 3 files changed, 93 insertions(+), 3 deletions(-)

diff --git a/dlls/mshtml/tests/script.c b/dlls/mshtml/tests/script.c
index e368824..efd161d 100644
--- a/dlls/mshtml/tests/script.c
+++ b/dlls/mshtml/tests/script.c
@@ -3043,6 +3043,7 @@ typedef struct {
     IInternetProtocolSink *sink;
     BINDINFO bind_info;
 
+    BSTR content_type;
     IStream *stream;
     char *data;
     ULONG size;
@@ -3068,6 +3069,7 @@ static void report_data(ProtocolHandler *This)
     IServiceProvider *service_provider;
     IHttpNegotiate *http_negotiate;
     WCHAR *addl_headers = NULL;
+    WCHAR headers_buf[128];
     BSTR headers, url;
     HRESULT hres;
 
@@ -3091,7 +3093,10 @@ static void report_data(ProtocolHandler *This)
 
         CoTaskMemFree(addl_headers);
 
-        headers = SysAllocString(L"HTTP/1.1 200 OK\r\n\r\n");
+        if(This->content_type)
+            swprintf(headers_buf, ARRAY_SIZE(headers_buf), L"HTTP/1.1 200 OK\r\nContent-Type: %s\r\n", This->content_type);
+
+        headers = SysAllocString(This->content_type ? headers_buf : L"HTTP/1.1 200 OK\r\n\r\n");
         hres = IHttpNegotiate_OnResponse(http_negotiate, 200, headers, NULL, NULL);
         ok(hres == S_OK, "OnResponse failed: %08lx\n", hres);
         SysFreeString(headers);
@@ -3250,6 +3255,7 @@ static ULONG WINAPI Protocol_Release(IInternetProtocolEx *iface)
         if(This->uri)
             IUri_Release(This->uri);
         ReleaseBindInfo(&This->bind_info);
+        SysFreeString(This->content_type);
         HeapFree(GetProcessHeap(), 0, This);
     }
 
@@ -3424,6 +3430,8 @@ static HRESULT WINAPI ProtocolEx_StartEx(IInternetProtocolEx *iface, IUri *uri,
     if(SUCCEEDED(hres)) {
         if(!lstrcmpW(query, L"?delay"))
             This->delay = 1000;
+        else if(!wcsncmp(query, L"?content-type=", sizeof("?content-type=")-1))
+            This->content_type = SysAllocString(query + sizeof("?content-type=")-1);
         SysFreeString(query);
     }
 
diff --git a/dlls/mshtml/tests/xhr.js b/dlls/mshtml/tests/xhr.js
index c450384..303c4ad 100644
--- a/dlls/mshtml/tests/xhr.js
+++ b/dlls/mshtml/tests/xhr.js
@@ -16,6 +16,8 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+var xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<a name=\"test\">wine</a>";
+
 function test_xhr() {
     var xhr = new XMLHttpRequest();
     var complete_cnt = 0, loadstart = false;
@@ -24,7 +26,9 @@ function test_xhr() {
         if(xhr.readyState != 4)
             return;
 
-        ok(xhr.responseText === "Testing...", "unexpected responseText " + xhr.responseText);
+        ok(xhr.responseText === xml, "unexpected responseText " + xhr.responseText);
+        ok(xhr.responseXML !== null, "unexpected null responseXML");
+
         if(complete_cnt++ && !("onloadend" in xhr))
             next_test();
     }
@@ -63,7 +67,55 @@ function test_xhr() {
         ok(xhr.withCredentials === true, "withCredentials = " + xhr.withCredentials);
         xhr.withCredentials = false;
     }
-    xhr.send("Testing...");
+    xhr.send(xml);
+}
+
+function test_content_types() {
+    var xhr = new XMLHttpRequest(), types, i = 0;
+    var v = document.documentMode;
+
+    var types = [
+        "",
+        "text/plain",
+        "text/html",
+        "wine/xml",
+        "xml"
+    ];
+    var xml_types = [
+        "text/xmL",
+        "apPliCation/xml",
+        "image/SvG+xml",
+        "Wine/Test+xml",
+        "++Xml",
+        "+xMl"
+    ];
+
+    function onload() {
+        ok(xhr.responseText === xml, "unexpected responseText " + xhr.responseText);
+        if(v < 10 || types === xml_types)
+            ok(xhr.responseXML !== null, "unexpected null responseXML for " + types[i]);
+        else
+            ok(xhr.responseXML === null, "unexpected non-null responseXML for " + types[i]);
+
+        if(++i >= types.length) {
+            if(types === xml_types) {
+                next_test();
+                return;
+            }
+            types = xml_types;
+            i = 0;
+        }
+        xhr = new XMLHttpRequest();
+        xhr.onload = onload;
+        xhr.open("POST", "echo.php?content-type=" + types[i], true);
+        xhr.setRequestHeader("X-Test", "True");
+        xhr.send(xml);
+    }
+
+    xhr.onload = onload;
+    xhr.open("POST", "echo.php?content-type=" + types[i], true);
+    xhr.setRequestHeader("X-Test", "True");
+    xhr.send(xml);
 }
 
 function test_abort() {
@@ -118,6 +170,7 @@ function test_timeout() {
 
 var tests = [
     test_xhr,
+    test_content_types,
     test_abort,
     test_timeout
 ];
diff --git a/dlls/mshtml/xmlhttprequest.c b/dlls/mshtml/xmlhttprequest.c
index 8fa91e9..0fadc10 100644
--- a/dlls/mshtml/xmlhttprequest.c
+++ b/dlls/mshtml/xmlhttprequest.c
@@ -374,6 +374,35 @@ static HRESULT WINAPI HTMLXMLHttpRequest_get_responseXML(IHTMLXMLHttpRequest *if
 
     TRACE("(%p)->(%p)\n", This, p);
 
+    if(dispex_compat_mode(&This->event_target.dispex) >= COMPAT_MODE_IE10) {
+        nsACString header, nscstr;
+        BOOL non_xml = FALSE;
+        const char *type;
+        nsresult nsres;
+
+        nsACString_InitDepend(&header, "Content-Type");
+        nsACString_InitDepend(&nscstr, NULL);
+        nsres = nsIXMLHttpRequest_GetResponseHeader(This->nsxhr, &header, &nscstr);
+        nsACString_Finish(&header);
+        if(NS_FAILED(nsres))
+            type = NULL;
+        else {
+            nsACString_GetData(&nscstr, &type);
+            if(!type[0])
+                type = NULL;
+        }
+        if(type && stricmp(type, "text/xml") && stricmp(type, "application/xml")) {
+            size_t len = strlen(type);
+            non_xml = len < 4 || stricmp(type + len - 4, "+xml");
+        }
+        nsACString_Finish(&nscstr);
+
+        if(non_xml) {
+            *p = NULL;
+            return S_OK;
+        }
+    }
+
     hres = CoCreateInstance(&CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (void**)&xmldoc);
     if(FAILED(hres)) {
         ERR("CoCreateInstance failed: %08lx\n", hres);
-- 
2.34.1




More information about the wine-devel mailing list