mshtml: Add IHTMLXMLHttpRequest::responseXML() method implementation. (try 2)

Zhenbo Li litimetal at gmail.com
Fri Nov 27 08:49:43 CST 2015


2015-11-14 17:33 GMT+08:00 Zhenbo Li <litimetal at gmail.com>:
>
> Also, I found that there was a hidden bug:
> As we will test these urls for responseXML:
>     static const char xml_url[] = "http://test.winehq.org/tests/xmltest.xml";
>     static const char large_page_url[] =
> "http://test.winehq.org/tests/data.php";
>
> char large_page_url is not a valid xml file, but native mshtml.dll can
> handle it properly. It shows we can't just past the responseText to
> msxml3.dll. I'll check it more carefully it later.

Hi, sorry for my late reply.
I tested it on testbot, and found that Windows mshtml.dll would return
an empty xml object


-- 
Have a nice day!
Zhenbo Li
-------------- next part --------------
diff --git a/dlls/mshtml/tests/xmlhttprequest.c b/dlls/mshtml/tests/xmlhttprequest.c
index 0997206..0610910 100644
--- a/dlls/mshtml/tests/xmlhttprequest.c
+++ b/dlls/mshtml/tests/xmlhttprequest.c
@@ -20,11 +20,13 @@
 
 #include <wine/test.h>
 #include <stdarg.h>
+#include <stdio.h>
 
 #include "windef.h"
 #include "winbase.h"
 #include "ole2.h"
 #include "mshtml.h"
+#include "objsafe.h"
 
 static BSTR a2bstr(const char *str)
 {
@@ -286,6 +288,7 @@ static IDispatchEx xmlhttprequest_onreadystatechange_obj = { &xmlhttprequest_onr
 
 static BOOL doc_complete;
 static IHTMLDocument2 *notif_doc;
+static BOOL ILLEGAL_XML;
 
 static HRESULT WINAPI PropertyNotifySink_QueryInterface(IPropertyNotifySink *iface,
         REFIID riid, void**ppv)
@@ -454,6 +457,109 @@ static void test_header(const struct HEADER_TYPE expect[], int num)
     }
 }
 
+static const char *debugstr_variant(const VARIANT *var)
+{
+    static char buf[400];
+
+    if (!var)
+        return "(null)";
+
+    switch (V_VT(var))
+    {
+    case VT_EMPTY:
+        return "{VT_EMPTY}";
+    case VT_BSTR:
+        sprintf(buf, "{VT_BSTR: %s}", wine_dbgstr_w(V_BSTR(var)));
+        break;
+    case VT_BOOL:
+        sprintf(buf, "{VT_BOOL: %x}", V_BOOL(var));
+        break;
+    case VT_UI4:
+        sprintf(buf, "{VT_UI4: %u}", V_UI4(var));
+        break;
+    default:
+        sprintf(buf, "{vt %d}", V_VT(var));
+        break;
+    }
+
+    return buf;
+}
+
+static void test_illegal_xml(IXMLDOMDocument *xmldom)
+{
+    IXMLDOMNode *first, *last;
+    VARIANT variant;
+    HRESULT hres;
+    BSTR bstr;
+
+    hres = IXMLDOMDocument_get_baseName(xmldom, NULL);
+    ok(hres == E_INVALIDARG, "Expect E_INVALIDARG, got %08x\n", hres);
+    hres = IXMLDOMDocument_get_baseName(xmldom, &bstr);
+    ok(hres == S_FALSE, "get_baseName failed: %08x\n", hres);
+    ok(bstr == NULL, "bstr(%p): %s\n", bstr, wine_dbgstr_w(bstr));
+    SysFreeString(bstr);
+
+    hres = IXMLDOMDocument_get_dataType(xmldom, NULL);
+    ok(hres == E_INVALIDARG, "Expect E_INVALIDARG, got %08x\n", hres);
+    hres = IXMLDOMDocument_get_dataType(xmldom, &variant);
+    ok(hres == S_FALSE, "get_dataType failed: %08x\n", hres);
+    ok(V_VT(&variant) == VT_NULL, "got %s\n", debugstr_variant(&variant));
+    VariantClear(&variant);
+
+    hres = IXMLDOMDocument_get_text(xmldom, &bstr);
+    ok(!strcmp_wa(bstr, ""), "text = %s\n", wine_dbgstr_w(bstr));
+    SysFreeString(bstr);
+
+    hres = IXMLDOMDocument_get_firstChild(xmldom, NULL);
+    ok(hres == E_INVALIDARG, "Expect E_INVALIDARG, got %08x\n", hres);
+
+    first = (void*)0xdeadbeef;
+    hres = IXMLDOMDocument_get_firstChild(xmldom, &first);
+    ok(hres == S_FALSE, "get_firstChild failed: %08x\n", hres);
+    ok(first == NULL, "first != NULL\n");
+
+    last = (void*)0xdeadbeef;
+    hres = IXMLDOMDocument_get_lastChild(xmldom, &last);
+    ok(hres == S_FALSE, "get_lastChild failed: %08x\n", hres);
+    ok(last == NULL, "last != NULL\n");
+}
+
+static void test_responseXML(void)
+{
+    IDispatch *disp;
+    IXMLDOMDocument *xmldom;
+    IObjectSafety *safety;
+    DWORD enabled = 0, supported = 0;
+    HRESULT hres;
+
+    disp = NULL;
+    hres = IHTMLXMLHttpRequest_get_responseXML(xhr, &disp);
+    ok(hres == S_OK, "get_responseXML failed: %08x\n", hres);
+    ok(disp != NULL, "disp == NULL\n");
+
+    xmldom = NULL;
+    hres = IDispatch_QueryInterface(disp, &IID_IXMLDOMDocument, (void**)&xmldom);
+    ok(hres == S_OK, "QueryInterface(IXMLDOMDocument) failed: %08x\n", hres);
+    ok(xmldom != NULL, "xmldom == NULL\n");
+
+    hres = IXMLDOMDocument_QueryInterface(xmldom, &IID_IObjectSafety, (void**)&safety);
+    ok(hres == S_OK, "QueryInterface IObjectSafety failed: %08x\n", hres);
+    hres = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled);
+    ok(hres == S_OK, "GetInterfaceSafetyOptions failed: %08x\n", hres);
+    ok(broken(supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA)) ||
+       supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER) /* msxml3 SP8+ */,
+        "Expected supported: (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER), got %08x\n", supported);
+    ok(enabled == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER),
+        "Expected enabled: (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER), got 0x%08x\n", enabled);
+    IObjectSafety_Release(safety);
+
+    if(ILLEGAL_XML)
+        test_illegal_xml(xmldom);
+
+    IXMLDOMDocument_Release(xmldom);
+    IDispatch_Release(disp);
+}
+
 static void test_sync_xhr(IHTMLDocument2 *doc, const char *xml_url, const char *expect_text)
 {
     VARIANT vbool, vempty, var;
@@ -468,6 +574,8 @@ static void test_sync_xhr(IHTMLDocument2 *doc, const char *xml_url, const char *
         {"Content-Type", "application/xml"}
     };
 
+    trace("test_sync_xhr\n");
+
     create_xmlhttprequest(doc);
     if(!xhr)
         return;
@@ -612,6 +720,8 @@ static void test_sync_xhr(IHTMLDocument2 *doc, const char *xml_url, const char *
             expect_text, wine_dbgstr_w(text));
     SysFreeString(text);
 
+    test_responseXML();
+
     IHTMLXMLHttpRequest_Release(xhr);
     xhr = NULL;
 }
@@ -786,6 +896,8 @@ static void test_async_xhr(IHTMLDocument2 *doc, const char *xml_url, const char
             expect_text, wine_dbgstr_w(text));
     SysFreeString(text);
 
+    test_responseXML();
+
     IHTMLXMLHttpRequest_Release(xhr);
     xhr = NULL;
 }
@@ -927,9 +1039,13 @@ START_TEST(xmlhttprequest)
     content_type = a2bstr("Content-Type");
     doc = create_doc_from_url(start_url);
     if(doc) {
+        ILLEGAL_XML = FALSE;
         test_sync_xhr(doc, xml_url, expect_response_text);
+        ILLEGAL_XML = TRUE;
         test_sync_xhr(doc, large_page_url, NULL);
+        ILLEGAL_XML = FALSE;
         test_async_xhr(doc, xml_url, expect_response_text);
+        ILLEGAL_XML = TRUE;
         test_async_xhr(doc, large_page_url, NULL);
         test_async_xhr_abort(doc, large_page_url);
         IHTMLDocument2_Release(doc);
diff --git a/dlls/mshtml/xmlhttprequest.c b/dlls/mshtml/xmlhttprequest.c
index fdfa31f..aa30b0f 100644
--- a/dlls/mshtml/xmlhttprequest.c
+++ b/dlls/mshtml/xmlhttprequest.c
@@ -30,6 +30,9 @@
 
 #include "mshtml_private.h"
 #include "htmlevent.h"
+#include "initguid.h"
+#include "msxml6.h"
+#include "objsafe.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
 
@@ -334,8 +337,52 @@ static HRESULT WINAPI HTMLXMLHttpRequest_get_responseText(IHTMLXMLHttpRequest *i
 static HRESULT WINAPI HTMLXMLHttpRequest_get_responseXML(IHTMLXMLHttpRequest *iface, IDispatch **p)
 {
     HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
-    FIXME("(%p)->(%p)\n", This, p);
-    return E_NOTIMPL;
+    IXMLDOMDocument *xmldoc = NULL;
+    BSTR str;
+    HRESULT hres;
+    VARIANT_BOOL vbool;
+    IObjectSafety *safety;
+
+    TRACE("(%p)->(%p)\n", This, p);
+
+    hres = CoCreateInstance(&CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (void**)&xmldoc);
+    if(FAILED(hres)) {
+        ERR("CoCreateInstance failed: %08x\n", hres);
+        return hres;
+    }
+
+    hres = IHTMLXMLHttpRequest_get_responseText(iface, &str);
+    if(FAILED(hres)) {
+        IXMLDOMDocument_Release(xmldoc);
+        ERR("get_responseText failed: %08x\n", hres);
+        return hres;
+    }
+
+    hres = IXMLDOMDocument_loadXML(xmldoc, str, &vbool);
+    SysFreeString(str);
+    if(hres != S_OK || vbool != VARIANT_TRUE) {
+        ERR("loadXML failed: %08x, returning an cmpty xmldoc\n", hres);
+    }
+
+    hres = IXMLDOMDocument_QueryInterface(xmldoc, &IID_IObjectSafety, (void**)&safety);
+    if(SUCCEEDED(hres)) {
+        hres = IObjectSafety_SetInterfaceSafetyOptions(safety, NULL,
+            INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER,
+            INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER);
+        IObjectSafety_Release(safety);
+        if(FAILED(hres)) {
+            ERR("SetInterfaceSafetyOptions(%p) failed: %08x\n", safety, hres);
+            IXMLDOMDocument_Release(xmldoc);
+            return hres;
+        }
+    } else {
+        ERR("QueryInterface(IID_IObjectSafety) failed: %08x\n", hres);
+        IXMLDOMDocument_Release(xmldoc);
+        return hres;
+    }
+
+    *p = (IDispatch*)xmldoc;
+    return S_OK;
 }
 
 static HRESULT WINAPI HTMLXMLHttpRequest_get_status(IHTMLXMLHttpRequest *iface, LONG *p)


More information about the wine-devel mailing list