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 #include +#include #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)