Module: wine Branch: master Commit: 5aa68f389cf2b5bfbca144030929769b0811cd69 URL: https://gitlab.winehq.org/wine/wine/-/commit/5aa68f389cf2b5bfbca144030929769...
Author: Gabriel Ivăncescu gabrielopcode@gmail.com Date: Wed Nov 1 17:00:40 2023 +0200
mshtml: Keep ref from the XMLHttpRequestFactory to the inner window.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com
---
dlls/mshtml/htmlwindow.c | 1 - dlls/mshtml/tests/events.c | 21 ++++++++++++++++++++- dlls/mshtml/xmlhttprequest.c | 25 +++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 2 deletions(-)
diff --git a/dlls/mshtml/htmlwindow.c b/dlls/mshtml/htmlwindow.c index 85794b7fe85..36aede7244e 100644 --- a/dlls/mshtml/htmlwindow.c +++ b/dlls/mshtml/htmlwindow.c @@ -3987,7 +3987,6 @@ static void HTMLWindow_unlink(DispatchEx *dispex) } if(This->xhr_factory) { HTMLXMLHttpRequestFactory *xhr_factory = This->xhr_factory; - This->xhr_factory->window = NULL; This->xhr_factory = NULL; IHTMLXMLHttpRequestFactory_Release(&xhr_factory->IHTMLXMLHttpRequestFactory_iface); } diff --git a/dlls/mshtml/tests/events.c b/dlls/mshtml/tests/events.c index 0ccb892603a..33654fe46b5 100644 --- a/dlls/mshtml/tests/events.c +++ b/dlls/mshtml/tests/events.c @@ -3237,14 +3237,17 @@ static void test_iframe_connections(IHTMLDocument2 *doc) static void test_window_refs(IHTMLDocument2 *doc) { IHTMLOptionElementFactory *option_factory; + IHTMLXMLHttpRequestFactory *xhr_factory; IHTMLImageElementFactory *image_factory; IHTMLWindow2 *self, *parent, *child; IHTMLOptionElement *option_elem; IHTMLImgElement *img_elem; + IHTMLXMLHttpRequest *xhr; IHTMLFrameBase2 *iframe; + IHTMLWindow5 *window5; IHTMLDocument6 *doc6; IHTMLElement2 *elem; - VARIANT vempty; + VARIANT vempty, var; HRESULT hres; BSTR bstr;
@@ -3265,6 +3268,16 @@ static void test_window_refs(IHTMLDocument2 *doc) ok(hres == S_OK, "get_contentWindow failed: %08lx\n", hres); IHTMLFrameBase2_Release(iframe);
+ hres = IHTMLWindow2_QueryInterface(window, &IID_IHTMLWindow5, (void**)&window5); + ok(hres == S_OK, "Could not get IHTMLWindow5: %08lx\n", hres); + hres = IHTMLWindow5_get_XMLHttpRequest(window5, &var); + ok(hres == S_OK, "get_XMLHttpRequest failed: %08lx\n", hres); + ok(V_VT(&var) == VT_DISPATCH, "V_VT(XMLHttpRequest) = %d\n", V_VT(&var)); + hres = IDispatch_QueryInterface(V_DISPATCH(&var), &IID_IHTMLXMLHttpRequestFactory, (void**)&xhr_factory); + ok(hres == S_OK, "Could not get IHTMLXMLHttpRequestFactory: %08lx\n", hres); + IHTMLWindow5_Release(window5); + VariantClear(&var); + hres = IHTMLWindow2_get_Image(window, &image_factory); ok(hres == S_OK, "get_Image failed: %08lx\n", hres); hres = IHTMLWindow2_get_Option(window, &option_factory); @@ -3286,6 +3299,12 @@ static void test_window_refs(IHTMLDocument2 *doc) IHTMLWindow2_Release(parent); IHTMLWindow2_Release(child);
+ hres = IHTMLXMLHttpRequestFactory_create(xhr_factory, &xhr); + todo_wine + ok(hres == S_OK, "create failed: %08lx\n", hres); + IHTMLXMLHttpRequestFactory_Release(xhr_factory); + if(hres == S_OK) IHTMLXMLHttpRequest_Release(xhr); + hres = IHTMLImageElementFactory_create(image_factory, vempty, vempty, &img_elem); ok(hres == S_OK, "create failed: %08lx\n", hres); ok(img_elem != NULL, "img_elem == NULL\n"); diff --git a/dlls/mshtml/xmlhttprequest.c b/dlls/mshtml/xmlhttprequest.c index 44f83dd8809..20049a13ee7 100644 --- a/dlls/mshtml/xmlhttprequest.c +++ b/dlls/mshtml/xmlhttprequest.c @@ -1686,6 +1686,9 @@ static HRESULT WINAPI HTMLXMLHttpRequestFactory_create(IHTMLXMLHttpRequestFactor
TRACE("(%p)->(%p)\n", This, p);
+ if(!This->window->base.outer_window) + return E_FAIL; + nsxhr = create_nsxhr(This->window->base.outer_window->nswindow); if(!nsxhr) return E_FAIL; @@ -1768,6 +1771,25 @@ static void *HTMLXMLHttpRequestFactory_query_interface(DispatchEx *dispex, REFII return NULL; }
+static void HTMLXMLHttpRequestFactory_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + HTMLXMLHttpRequestFactory *This = factory_from_DispatchEx(dispex); + + if(This->window) + note_cc_edge((nsISupports*)&This->window->base.IHTMLWindow2_iface, "window", cb); +} + +static void HTMLXMLHttpRequestFactory_unlink(DispatchEx *dispex) +{ + HTMLXMLHttpRequestFactory *This = factory_from_DispatchEx(dispex); + + if(This->window) { + HTMLInnerWindow *window = This->window; + This->window = NULL; + IHTMLWindow2_Release(&window->base.IHTMLWindow2_iface); + } +} + static void HTMLXMLHttpRequestFactory_destructor(DispatchEx *dispex) { HTMLXMLHttpRequestFactory *This = factory_from_DispatchEx(dispex); @@ -1800,6 +1822,8 @@ static HRESULT HTMLXMLHttpRequestFactory_value(DispatchEx *iface, LCID lcid, WOR static const dispex_static_data_vtbl_t HTMLXMLHttpRequestFactory_dispex_vtbl = { .query_interface = HTMLXMLHttpRequestFactory_query_interface, .destructor = HTMLXMLHttpRequestFactory_destructor, + .traverse = HTMLXMLHttpRequestFactory_traverse, + .unlink = HTMLXMLHttpRequestFactory_unlink, .value = HTMLXMLHttpRequestFactory_value };
@@ -1824,6 +1848,7 @@ HRESULT HTMLXMLHttpRequestFactory_Create(HTMLInnerWindow* window, HTMLXMLHttpReq
ret->IHTMLXMLHttpRequestFactory_iface.lpVtbl = &HTMLXMLHttpRequestFactoryVtbl; ret->window = window; + IHTMLWindow2_AddRef(&window->base.IHTMLWindow2_iface);
init_dispatch(&ret->dispex, &HTMLXMLHttpRequestFactory_dispex, dispex_compat_mode(&window->event_target.dispex));