Here's a list of usages of `base.outer_window` that may be impacted by the change and my analysis/fixes. Note that I specifically did not look for `document->outer_window` since that one was already holding it forever, so it's out of scope for this MR (whether it's correct or not, the behavior is the same after this MR).
I also didn't consider some cases that already **did not check** for it being NULL or not, because they would have crashed earlier before anyway (they'd still crash now if outer window gets killed, but it's out of scope of the MR as I said). For those that says "Handled" it means I've added checks so that the behavior is same as before, i.e. detached inner windows behave as if outer window is NULL.
* `htmldoc.c/HTMLDocument_get_mimeType`: Changed so it doesn't rely on outer window. * `htmldoc.c/HTMLDocument7_get_defaultView`: This is actually fixed by these patches. * `htmlform.c/HTMLFormElement_submit`: Handled. * `htmlstorage.c/send_storage_event`: Fixed in a separate patch with tests, since it follows the outer window. * `htmlwindow.c/check_target_origin`: This (along with many other methods) can't have it NULL anymore or detached, since the caller must hold a ref to the outer window, and they're not called from our objects holding ref to inner window only. * `htmlwindow.c/HTMLWindowSP_QueryService`: This uses the outer window to obtain the browser and the doc obj, so it's fine. * `mutation.c/set_document_mode`: Handled. * `navigate.c/BindCallbackRedirect_Redirect`: Handled. * `navigate.c/nsAsyncVerifyRedirectCallback_OnRedirectVerifyCallback`: Handled. * `navigate.c/nsChannelBSC_init_bindinfo`: Uses the outer window to obtain the browser and doc obj to set a flag, so it's harmless and probably correct this way. * `navigate.c/handle_navigation_error`: Handled. * `navigate.c/handle_extern_mime_navigation`: Handled. * `omnavigator.c/OmHistory_get_length`: This is actually fixed by these patches. * `script.c/ActiveScriptSite_GetItemInfo`: Handled. * `script.c/ActiveScriptSiteWindow_GetWindow`: Handled.
-- v6: mshtml/tests: Fix XHR leak in test_window_refs. mshtml: Get rid of outer_window member in HTMLDocumentNode. mshtml: Remove the inner window ref from the doc only when it is actually mshtml: Don't check for NULL outer_window from within HTMLWindow* methods. mshtml: Don't attempt to send storage events after outer window is detached. mshtml/tests: Improve the iframe navigation test. mshtml: Don't rely on the outer_window in document.mimeType.
From: Gabriel Ivăncescu gabrielopcode@gmail.com
This would have crashed on detached windows, and checking the navigation_start time has the same effect except it's decoupled from the outer window.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmldoc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/mshtml/htmldoc.c b/dlls/mshtml/htmldoc.c index 540bbbd1626..3ace8e88ec2 100644 --- a/dlls/mshtml/htmldoc.c +++ b/dlls/mshtml/htmldoc.c @@ -1287,7 +1287,7 @@ static HRESULT WINAPI HTMLDocument_get_mimeType(IHTMLDocument2 *iface, BSTR *p)
*p = NULL;
- if(This->window && This->window->base.outer_window->readystate == READYSTATE_UNINITIALIZED) + if(This->window && !This->window->navigation_start_time) return (*p = SysAllocString(L"")) ? S_OK : E_FAIL;
nsAString_InitDepend(&nsstr, NULL);
From: Gabriel Ivăncescu gabrielopcode@gmail.com
It was confusing before since it made it seem like it might use the outer window, while in fact the document is unchanged on native. Now the "new" doc is used for navigating, since it's already checked to be the same as the iframes_doc (but that test fails in wine and is todo_wine).
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/tests/events.c | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-)
diff --git a/dlls/mshtml/tests/events.c b/dlls/mshtml/tests/events.c index b76e7982638..0f0246bfe5c 100644 --- a/dlls/mshtml/tests/events.c +++ b/dlls/mshtml/tests/events.c @@ -173,16 +173,16 @@ static const char iframe_doc_str[] =
static void navigate(IHTMLDocument2*,const WCHAR*);
-static BOOL iface_cmp(IUnknown *iface1, IUnknown *iface2) +static BOOL iface_cmp(void *iface1, void *iface2) { IUnknown *unk1, *unk2;
if(iface1 == iface2) return TRUE;
- IUnknown_QueryInterface(iface1, &IID_IUnknown, (void**)&unk1); + IUnknown_QueryInterface((IUnknown *)iface1, &IID_IUnknown, (void**)&unk1); IUnknown_Release(unk1); - IUnknown_QueryInterface(iface2, &IID_IUnknown, (void**)&unk2); + IUnknown_QueryInterface((IUnknown *)iface2, &IID_IUnknown, (void**)&unk2); IUnknown_Release(unk2);
return unk1 == unk2; @@ -3170,8 +3170,8 @@ static IHTMLDocument2 *get_iframe_doc(IHTMLIFrameElement *iframe)
static void test_iframe_connections(IHTMLDocument2 *doc) { + IHTMLDocument2 *iframes_doc, *new_doc; IHTMLIFrameElement *iframe; - IHTMLDocument2 *iframes_doc; DWORD cookie; IConnectionPoint *cp; IHTMLElement *element; @@ -3185,7 +3185,6 @@ static void test_iframe_connections(IHTMLDocument2 *doc) IHTMLElement_Release(element);
iframes_doc = get_iframe_doc(iframe); - IHTMLIFrameElement_Release(iframe);
cookie = register_cp((IUnknown*)iframes_doc, &IID_IDispatch, (IUnknown*)&div_onclick_disp);
@@ -3215,23 +3214,38 @@ static void test_iframe_connections(IHTMLDocument2 *doc) ok(hres == S_OK, "put_URL failed: %08lx\n", hres); SysFreeString(str);
+ new_doc = get_iframe_doc(iframe); + ok(iface_cmp(new_doc, iframes_doc), "new_doc != iframes_doc\n"); + IHTMLDocument2_Release(new_doc); + SET_EXPECT(iframe_onload); pump_msgs(&called_iframe_onload); CHECK_CALLED(iframe_onload);
+ new_doc = get_iframe_doc(iframe); + todo_wine + ok(iface_cmp(new_doc, iframes_doc), "new_doc != iframes_doc\n"); + str = SysAllocString(L"about:test"); - hres = IHTMLDocument2_put_URL(iframes_doc, str); + hres = IHTMLDocument2_put_URL(new_doc, str); ok(hres == S_OK, "put_URL failed: %08lx\n", hres); + IHTMLDocument2_Release(new_doc); SysFreeString(str);
SET_EXPECT(iframe_onload); pump_msgs(&called_iframe_onload); CHECK_CALLED(iframe_onload); + + new_doc = get_iframe_doc(iframe); + todo_wine + ok(iface_cmp(new_doc, iframes_doc), "new_doc != iframes_doc\n"); + IHTMLDocument2_Release(new_doc); }else { win_skip("Skipping iframe onload tests on IE older than 9.\n"); }
IHTMLDocument2_Release(iframes_doc); + IHTMLIFrameElement_Release(iframe); }
static void test_window_refs(IHTMLDocument2 *doc)
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlstorage.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/dlls/mshtml/htmlstorage.c b/dlls/mshtml/htmlstorage.c index efd4b2d88ae..06d16e4e4aa 100644 --- a/dlls/mshtml/htmlstorage.c +++ b/dlls/mshtml/htmlstorage.c @@ -322,6 +322,11 @@ static HRESULT send_storage_event(HTMLStorage *storage, BSTR key, BSTR old_value HRESULT hres = S_OK;
ctx.url = NULL; + + /* FIXME: Events are actually sent to the current window on native, even if we're detached. */ + if(!window->base.outer_window) + goto done; + if(window->base.outer_window->uri_nofrag) { hres = IUri_GetDisplayUri(window->base.outer_window->uri_nofrag, &ctx.url); if(hres != S_OK)
From: Gabriel Ivăncescu gabrielopcode@gmail.com
These methods are not called from any of our objects that hold ref to the inner window only, and since we return outer windows to external callers now, they *must* have a ref to the outer window, which effectively means these cannot be NULL. And some other places didn't check for NULL either (e.g. get_parent).
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlwindow.c | 68 ++++++++++++++++------------------------ 1 file changed, 27 insertions(+), 41 deletions(-)
diff --git a/dlls/mshtml/htmlwindow.c b/dlls/mshtml/htmlwindow.c index fc0a03e3bf8..fa99c453989 100644 --- a/dlls/mshtml/htmlwindow.c +++ b/dlls/mshtml/htmlwindow.c @@ -584,7 +584,7 @@ static HRESULT WINAPI HTMLWindow2_alert(IHTMLWindow2 *iface, BSTR message)
TRACE("(%p)->(%s)\n", This, debugstr_w(message));
- if(!This->outer_window || !This->outer_window->browser) + if(!This->outer_window->browser) return E_UNEXPECTED;
if(!LoadStringW(get_shdoclc(), IDS_MESSAGE_BOX_TITLE, title, ARRAY_SIZE(title))) { @@ -617,7 +617,7 @@ static HRESULT WINAPI HTMLWindow2_confirm(IHTMLWindow2 *iface, BSTR message,
if(!confirmed) return E_INVALIDARG; - if(!This->outer_window || !This->outer_window->browser) + if(!This->outer_window->browser) return E_UNEXPECTED;
if(!LoadStringW(get_shdoclc(), IDS_MESSAGE_BOX_TITLE, wszTitle, ARRAY_SIZE(wszTitle))) { @@ -711,7 +711,7 @@ static HRESULT WINAPI HTMLWindow2_prompt(IHTMLWindow2 *iface, BSTR message,
TRACE("(%p)->(%s %s %p)\n", This, debugstr_w(message), debugstr_w(dststr), textdata);
- if(!This->outer_window || !This->outer_window->browser) + if(!This->outer_window->browser) return E_UNEXPECTED;
if(textdata) V_VT(textdata) = VT_NULL; @@ -846,7 +846,7 @@ static HRESULT WINAPI HTMLWindow2_close(IHTMLWindow2 *iface)
TRACE("(%p)\n", This);
- if(!window || !window->browser) { + if(!window->browser) { FIXME("No document object\n"); return E_FAIL; } @@ -953,7 +953,7 @@ static HRESULT WINAPI HTMLWindow2_open(IHTMLWindow2 *iface, BSTR url, BSTR name, if(replace) FIXME("unsupported relace argument\n");
- if(!window || !window->browser || !window->uri_nofrag) + if(!window->browser || !window->uri_nofrag) return E_UNEXPECTED;
if(name && *name == '_') { @@ -1310,7 +1310,7 @@ static HRESULT WINAPI HTMLWindow2_focus(IHTMLWindow2 *iface)
TRACE("(%p)->()\n", This);
- if(!This->outer_window || !This->outer_window->browser) + if(!This->outer_window->browser) return E_UNEXPECTED;
SetFocus(This->outer_window->browser->doc->hwnd); @@ -1477,7 +1477,7 @@ static HRESULT WINAPI HTMLWindow2_get_external(IHTMLWindow2 *iface, IDispatch **
TRACE("(%p)->(%p)\n", This, p);
- if(!This->outer_window || !This->outer_window->browser) + if(!This->outer_window->browser) return E_UNEXPECTED;
*p = NULL; @@ -2396,9 +2396,6 @@ static HRESULT WINAPI HTMLWindow7_getComputedStyle(IHTMLWindow7 *iface, IHTMLDOM
TRACE("(%p)->(%p %s %p)\n", This, node, debugstr_w(pseudo_elt), p);
- if(!This->outer_window || !This->inner_window) - return E_UNEXPECTED; - hres = IHTMLDOMNode_QueryInterface(node, &IID_IHTMLElement, (void**)&elem); if(FAILED(hres)) return hres; @@ -2832,7 +2829,7 @@ static HRESULT WINAPI HTMLPrivateWindow_SuperNavigate(IHTMLPrivateWindow *iface, if(flags & ~2) FIXME("unimplemented flags %lx\n", flags & ~2);
- if(!window || !window->browser) + if(!window->browser) return E_FAIL;
if(window->browser->doc->hostui) { @@ -3641,6 +3638,9 @@ static HRESULT WINAPI WindowDispEx_GetDispID(IDispatchEx *iface, BSTR bstrName, { HTMLWindow *This = impl_from_IDispatchEx(iface); HTMLInnerWindow *window = This->inner_window; + HTMLOuterWindow *frame; + global_prop_t *prop; + IHTMLElement *elem; HRESULT hres;
TRACE("(%p)->(%s %lx %p)\n", This, debugstr_w(bstrName), grfdex, pid); @@ -3653,38 +3653,27 @@ static HRESULT WINAPI WindowDispEx_GetDispID(IDispatchEx *iface, BSTR bstrName, if(hres != DISP_E_UNKNOWNNAME) return hres;
- if(This->outer_window) { - HTMLOuterWindow *frame; - - hres = get_frame_by_name(This->outer_window, bstrName, FALSE, &frame); - if(SUCCEEDED(hres) && frame) { - global_prop_t *prop; - - prop = alloc_global_prop(window, GLOBAL_FRAMEVAR, bstrName); - if(!prop) - return E_OUTOFMEMORY; + hres = get_frame_by_name(This->outer_window, bstrName, FALSE, &frame); + if(SUCCEEDED(hres) && frame) { + prop = alloc_global_prop(window, GLOBAL_FRAMEVAR, bstrName); + if(!prop) + return E_OUTOFMEMORY;
- *pid = prop_to_dispid(window, prop); - return S_OK; - } + *pid = prop_to_dispid(window, prop); + return S_OK; }
- if(window->doc) { - global_prop_t *prop; - IHTMLElement *elem; - - hres = IHTMLDocument3_getElementById(&window->base.inner_window->doc->IHTMLDocument3_iface, - bstrName, &elem); - if(SUCCEEDED(hres) && elem) { - IHTMLElement_Release(elem); + hres = IHTMLDocument3_getElementById(&window->base.inner_window->doc->IHTMLDocument3_iface, + bstrName, &elem); + if(SUCCEEDED(hres) && elem) { + IHTMLElement_Release(elem);
- prop = alloc_global_prop(window, GLOBAL_ELEMENTVAR, bstrName); - if(!prop) - return E_OUTOFMEMORY; + prop = alloc_global_prop(window, GLOBAL_ELEMENTVAR, bstrName); + if(!prop) + return E_OUTOFMEMORY;
- *pid = prop_to_dispid(window, prop); - return S_OK; - } + *pid = prop_to_dispid(window, prop); + return S_OK; }
return DISP_E_UNKNOWNNAME; @@ -4120,9 +4109,6 @@ static HRESULT HTMLWindow_invoke(DispatchEx *dispex, DISPID id, LCID lcid, WORD return E_NOTIMPL; } case GLOBAL_FRAMEVAR: - if(!This->base.outer_window) - return E_UNEXPECTED; - switch(flags) { case DISPATCH_PROPERTYGET: { HTMLOuterWindow *frame;
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Not on every detach.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmldoc.c | 14 +++++++------- dlls/mshtml/tests/events.c | 7 +++++++ 2 files changed, 14 insertions(+), 7 deletions(-)
diff --git a/dlls/mshtml/htmldoc.c b/dlls/mshtml/htmldoc.c index 3ace8e88ec2..cd31b1b25f6 100644 --- a/dlls/mshtml/htmldoc.c +++ b/dlls/mshtml/htmldoc.c @@ -5707,12 +5707,6 @@ void detach_document_node(HTMLDocumentNode *doc) { unsigned i;
- if(doc->window) { - HTMLInnerWindow *window = doc->window; - doc->window = NULL; - IHTMLWindow2_Release(&window->base.IHTMLWindow2_iface); - } - while(!list_empty(&doc->plugin_hosts)) detach_plugin_host(LIST_ENTRY(list_head(&doc->plugin_hosts), PluginHost, entry));
@@ -5884,14 +5878,20 @@ static void HTMLDocumentNode_traverse(DispatchEx *dispex, nsCycleCollectionTrave static void HTMLDocumentNode_unlink(DispatchEx *dispex) { HTMLDocumentNode *This = impl_from_DispatchEx(dispex); + HTMLInnerWindow *window = This->window; HTMLDOMNode_unlink(dispex);
+ if(window) { + This->window = NULL; + IHTMLWindow2_Release(&window->base.IHTMLWindow2_iface); + } + if(This->dom_document) { release_document_mutation(This); detach_document_node(This); This->dom_document = NULL; This->html_document = NULL; - }else if(This->window) { + }else if(window) { detach_document_node(This); } } diff --git a/dlls/mshtml/tests/events.c b/dlls/mshtml/tests/events.c index 0f0246bfe5c..4b775ceb8b8 100644 --- a/dlls/mshtml/tests/events.c +++ b/dlls/mshtml/tests/events.c @@ -3589,7 +3589,14 @@ static void test_doc_obj(IHTMLDocument2 *doc) ok(hres == S_OK, "get_document failed: %08lx\n", hres); ok(doc_node != doc_node2, "doc_node == doc_node2\n"); IHTMLDocument2_Release(doc_node2); + + hres = IHTMLDocument2_get_parentWindow(doc_node, &window2); + todo_wine + ok(hres == S_OK, "get_parentWindow failed: %08lx\n", hres); + todo_wine + ok(window == window2, "window != window2\n"); IHTMLDocument2_Release(doc_node); + if(hres == S_OK) IHTMLWindow2_Release(window2);
hres = IHTMLWindow2_get_location(window, &location2); ok(hres == S_OK, "get_location failed: %08lx\n", hres);
From: Gabriel Ivăncescu gabrielopcode@gmail.com
outer_window was wrong because it didn't even hold any sort of ref to the outer window in the first place...
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/editor.c | 6 ++--- dlls/mshtml/htmlanchor.c | 6 ++--- dlls/mshtml/htmldoc.c | 44 ++++++++++++++++++------------------ dlls/mshtml/htmlframe.c | 6 ++--- dlls/mshtml/mshtml_private.h | 1 - dlls/mshtml/mutation.c | 2 +- dlls/mshtml/nsevents.c | 10 ++++---- dlls/mshtml/olecmd.c | 4 ++-- dlls/mshtml/pluginhost.c | 4 ++-- dlls/mshtml/secmgr.c | 8 +++---- 10 files changed, 45 insertions(+), 46 deletions(-)
diff --git a/dlls/mshtml/editor.c b/dlls/mshtml/editor.c index e4a16956e46..1173e8e68fc 100644 --- a/dlls/mshtml/editor.c +++ b/dlls/mshtml/editor.c @@ -146,7 +146,7 @@ static DWORD query_ns_edit_status(HTMLDocumentNode *doc, const char *nscmd) nsICommandParams *nsparam; cpp_bool b = FALSE;
- if(doc->browser->usermode != EDITMODE || doc->outer_window->readystate < READYSTATE_INTERACTIVE) + if(doc->browser->usermode != EDITMODE || doc->window->base.outer_window->readystate < READYSTATE_INTERACTIVE) return OLECMDF_SUPPORTED;
if(nscmd) { @@ -180,7 +180,7 @@ static DWORD query_align_status(HTMLDocumentNode *doc, const WCHAR *align) cpp_bool b; nsresult nsres;
- if(doc->browser->usermode != EDITMODE || doc->outer_window->readystate < READYSTATE_INTERACTIVE) + if(doc->browser->usermode != EDITMODE || doc->window->base.outer_window->readystate < READYSTATE_INTERACTIVE) return OLECMDF_SUPPORTED;
if(!doc->html_document) { @@ -669,7 +669,7 @@ static HRESULT query_justify(HTMLDocumentNode *doc, OLECMD *cmd) case IDM_JUSTIFYLEFT: TRACE("(%p) IDM_JUSTIFYLEFT\n", doc); /* FIXME: We should set OLECMDF_LATCHED only if it's set explicitly. */ - if(doc->browser->usermode != EDITMODE || doc->outer_window->readystate < READYSTATE_INTERACTIVE) + if(doc->browser->usermode != EDITMODE || doc->window->base.outer_window->readystate < READYSTATE_INTERACTIVE) cmd->cmdf = OLECMDF_SUPPORTED; else cmd->cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED; diff --git a/dlls/mshtml/htmlanchor.c b/dlls/mshtml/htmlanchor.c index 5398f87ce55..5f8a98faf17 100644 --- a/dlls/mshtml/htmlanchor.c +++ b/dlls/mshtml/htmlanchor.c @@ -49,11 +49,11 @@ static HRESULT navigate_href_new_window(HTMLElement *element, nsAString *href_st HRESULT hres;
nsAString_GetData(href_str, &href); - hres = create_relative_uri(element->node.doc->outer_window, href, &uri); + hres = create_relative_uri(element->node.doc->window->base.outer_window, href, &uri); if(FAILED(hres)) return hres;
- hres = navigate_new_window(element->node.doc->outer_window, uri, target, NULL, NULL); + hres = navigate_new_window(element->node.doc->window->base.outer_window, uri, target, NULL, NULL); IUri_Release(uri); return hres; } @@ -110,7 +110,7 @@ static HRESULT navigate_href(HTMLElement *element, nsAString *href_str, nsAStrin const PRUnichar *href; HRESULT hres;
- window = get_target_window(element->node.doc->outer_window, target_str, &use_new_window); + window = get_target_window(element->node.doc->window->base.outer_window, target_str, &use_new_window); if(!window) { if(use_new_window) { const PRUnichar *target; diff --git a/dlls/mshtml/htmldoc.c b/dlls/mshtml/htmldoc.c index cd31b1b25f6..02857be3bed 100644 --- a/dlls/mshtml/htmldoc.c +++ b/dlls/mshtml/htmldoc.c @@ -905,7 +905,7 @@ static HRESULT WINAPI HTMLDocument_get_readyState(IHTMLDocument2 *iface, BSTR *p if(!p) return E_POINTER;
- return get_readystate_string(This->outer_window ? This->outer_window->readystate : 0, p); + return get_readystate_string(This->window && This->window->base.outer_window ? This->window->base.outer_window->readystate : 0, p); }
static HRESULT WINAPI HTMLDocument_get_frames(IHTMLDocument2 *iface, IHTMLFramesCollection2 **p) @@ -914,11 +914,11 @@ static HRESULT WINAPI HTMLDocument_get_frames(IHTMLDocument2 *iface, IHTMLFrames
TRACE("(%p)->(%p)\n", This, p);
- if(!This->outer_window) { + if(!This->window || !This->window->base.outer_window) { /* Not implemented by IE */ return E_NOTIMPL; } - return IHTMLWindow2_get_frames(&This->outer_window->base.IHTMLWindow2_iface, p); + return IHTMLWindow2_get_frames(&This->window->base.outer_window->base.IHTMLWindow2_iface, p); }
static HRESULT WINAPI HTMLDocument_get_embeds(IHTMLDocument2 *iface, IHTMLElementCollection **p) @@ -1094,12 +1094,12 @@ static HRESULT WINAPI HTMLDocument_put_URL(IHTMLDocument2 *iface, BSTR v)
TRACE("(%p)->(%s)\n", This, debugstr_w(v));
- if(!This->outer_window) { + if(!This->window || !This->window->base.outer_window) { FIXME("No window available\n"); return E_FAIL; }
- return navigate_url(This->outer_window, v, This->outer_window->uri, BINDING_NAVIGATED); + return navigate_url(This->window->base.outer_window, v, This->window->base.outer_window->uri, BINDING_NAVIGATED); }
static HRESULT WINAPI HTMLDocument_get_URL(IHTMLDocument2 *iface, BSTR *p) @@ -1108,7 +1108,8 @@ static HRESULT WINAPI HTMLDocument_get_URL(IHTMLDocument2 *iface, BSTR *p)
TRACE("(%p)->(%p)\n", iface, p);
- *p = SysAllocString(This->outer_window && This->outer_window->url ? This->outer_window->url : L"about:blank"); + *p = SysAllocString(This->window && This->window->base.outer_window && This->window->base.outer_window->url ? + This->window->base.outer_window->url : L"about:blank"); return *p ? S_OK : E_OUTOFMEMORY; }
@@ -1149,12 +1150,12 @@ static HRESULT WINAPI HTMLDocument_get_domain(IHTMLDocument2 *iface, BSTR *p) return E_NOTIMPL; }
- if(This->outer_window && !This->outer_window->uri) + if(This->window && This->window->base.outer_window && !This->window->base.outer_window->uri) return E_FAIL;
nsAString_Init(&nsstr, NULL); nsres = nsIDOMHTMLDocument_GetDomain(This->html_document, &nsstr); - if(NS_SUCCEEDED(nsres) && This->outer_window && This->outer_window->uri) { + if(NS_SUCCEEDED(nsres) && This->window && This->window->base.outer_window && This->window->base.outer_window->uri) { const PRUnichar *str; HRESULT hres;
@@ -1162,7 +1163,7 @@ static HRESULT WINAPI HTMLDocument_get_domain(IHTMLDocument2 *iface, BSTR *p) if(!*str) { TRACE("Gecko returned empty string, fallback to loaded URL.\n"); nsAString_Finish(&nsstr); - hres = IUri_GetHost(This->outer_window->uri, p); + hres = IUri_GetHost(This->window->base.outer_window->uri, p); return FAILED(hres) ? hres : S_OK; } } @@ -1177,10 +1178,10 @@ static HRESULT WINAPI HTMLDocument_put_cookie(IHTMLDocument2 *iface, BSTR v)
TRACE("(%p)->(%s)\n", This, debugstr_w(v));
- if(!This->outer_window) + if(!This->window || !This->window->base.outer_window) return S_OK;
- bret = InternetSetCookieExW(This->outer_window->url, NULL, v, 0, 0); + bret = InternetSetCookieExW(This->window->base.outer_window->url, NULL, v, 0, 0); if(!bret) { FIXME("InternetSetCookieExW failed: %lu\n", GetLastError()); return HRESULT_FROM_WIN32(GetLastError()); @@ -1197,13 +1198,13 @@ static HRESULT WINAPI HTMLDocument_get_cookie(IHTMLDocument2 *iface, BSTR *p)
TRACE("(%p)->(%p)\n", This, p);
- if(!This->outer_window) { + if(!This->window || !This->window->base.outer_window) { *p = NULL; return S_OK; }
size = 0; - bret = InternetGetCookieExW(This->outer_window->url, NULL, NULL, &size, 0, NULL); + bret = InternetGetCookieExW(This->window->base.outer_window->url, NULL, NULL, &size, 0, NULL); if(!bret && GetLastError() != ERROR_INSUFFICIENT_BUFFER) { WARN("InternetGetCookieExW failed: %lu\n", GetLastError()); *p = NULL; @@ -1219,7 +1220,7 @@ static HRESULT WINAPI HTMLDocument_get_cookie(IHTMLDocument2 *iface, BSTR *p) if(!*p) return E_OUTOFMEMORY;
- bret = InternetGetCookieExW(This->outer_window->url, NULL, *p, &size, 0, NULL); + bret = InternetGetCookieExW(This->window->base.outer_window->url, NULL, *p, &size, 0, NULL); if(!bret) { ERR("InternetGetCookieExW failed: %lu\n", GetLastError()); return E_FAIL; @@ -1448,7 +1449,7 @@ static HRESULT WINAPI HTMLDocument_open(IHTMLDocument2 *iface, BSTR url, VARIANT
*pomWindowResult = NULL;
- if(!This->outer_window) + if(!This->window || !This->window->base.outer_window) return E_FAIL;
if(!This->dom_document) { @@ -1475,8 +1476,8 @@ static HRESULT WINAPI HTMLDocument_open(IHTMLDocument2 *iface, BSTR url, VARIANT if(tmp) nsISupports_Release(tmp);
- *pomWindowResult = (IDispatch*)&This->outer_window->base.IHTMLWindow2_iface; - IHTMLWindow2_AddRef(&This->outer_window->base.IHTMLWindow2_iface); + *pomWindowResult = (IDispatch*)&This->window->base.outer_window->base.IHTMLWindow2_iface; + IHTMLWindow2_AddRef(&This->window->base.outer_window->base.IHTMLWindow2_iface); return S_OK; }
@@ -2349,7 +2350,7 @@ static HRESULT WINAPI HTMLDocument3_get_documentElement(IHTMLDocument3 *iface, I
TRACE("(%p)->(%p)\n", This, p);
- if(This->outer_window && This->outer_window->readystate == READYSTATE_UNINITIALIZED) { + if(This->window && This->window->base.outer_window && This->window->base.outer_window->readystate == READYSTATE_UNINITIALIZED) { *p = NULL; return S_OK; } @@ -4876,7 +4877,7 @@ static void HTMLDocumentNode_on_advise(IUnknown *iface, cp_static_data_t *cp) { HTMLDocumentNode *This = CONTAINING_RECORD((IHTMLDocument2*)iface, HTMLDocumentNode, IHTMLDocument2_iface);
- if(This->outer_window) + if(This->window && This->window->base.outer_window) update_doc_cp_events(This, cp); }
@@ -6070,10 +6071,10 @@ static HRESULT HTMLDocumentNode_location_hook(DispatchEx *dispex, WORD flags, DI { HTMLDocumentNode *This = impl_from_DispatchEx(dispex);
- if(!(flags & DISPATCH_PROPERTYPUT) || !This->outer_window) + if(!(flags & DISPATCH_PROPERTYPUT) || !This->window || !This->window->base.outer_window) return S_FALSE;
- return IDispatchEx_InvokeEx(&This->outer_window->base.IDispatchEx_iface, DISPID_IHTMLWINDOW2_LOCATION, + return IDispatchEx_InvokeEx(&This->window->base.outer_window->base.IDispatchEx_iface, DISPID_IHTMLWINDOW2_LOCATION, 0, flags, dp, res, ei, caller); }
@@ -6187,7 +6188,6 @@ static HTMLDocumentNode *alloc_doc_node(HTMLDocumentObj *doc_obj, HTMLInnerWindo doc->IDocumentRange_iface.lpVtbl = &DocumentRangeVtbl;
doc->doc_obj = doc_obj; - doc->outer_window = window ? window->base.outer_window : NULL; doc->window = window;
if(window) diff --git a/dlls/mshtml/htmlframe.c b/dlls/mshtml/htmlframe.c index 1a78dc3cc07..28bf42e2569 100644 --- a/dlls/mshtml/htmlframe.c +++ b/dlls/mshtml/htmlframe.c @@ -50,7 +50,7 @@ static HRESULT set_frame_doc(HTMLFrameBase *frame, nsIDOMDocument *nsdoc) window = mozwindow_to_window(mozwindow); if(!window && frame->element.node.doc->browser) { hres = create_outer_window(frame->element.node.doc->browser, mozwindow, - frame->element.node.doc->outer_window, &window); + frame->element.node.doc->window->base.outer_window, &window);
/* Don't hold ref to the created window; the parent keeps ref to it */ if(SUCCEEDED(hres)) @@ -132,7 +132,7 @@ static HRESULT WINAPI HTMLFrameBase_put_src(IHTMLFrameBase *iface, BSTR v)
TRACE("(%p)->(%s)\n", This, debugstr_w(v));
- if(!This->content_window || !This->element.node.doc || !This->element.node.doc->outer_window) { + if(!This->content_window || !This->element.node.doc || !This->element.node.doc->window || !This->element.node.doc->window->base.outer_window) { nsAString nsstr; nsresult nsres;
@@ -150,7 +150,7 @@ static HRESULT WINAPI HTMLFrameBase_put_src(IHTMLFrameBase *iface, BSTR v) return S_OK; }
- return navigate_url(This->content_window, v, This->element.node.doc->outer_window->uri, BINDING_NAVIGATED); + return navigate_url(This->content_window, v, This->element.node.doc->window->base.outer_window->uri, BINDING_NAVIGATED); }
static HRESULT WINAPI HTMLFrameBase_get_src(IHTMLFrameBase *iface, BSTR *p) diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 40dcb0ebfab..db37375c089 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -940,7 +940,6 @@ struct HTMLDocumentNode {
nsIDocumentObserver nsIDocumentObserver_iface; ConnectionPointContainer cp_container; - HTMLOuterWindow *outer_window; HTMLInnerWindow *window; HTMLDocumentObj *doc_obj;
diff --git a/dlls/mshtml/mutation.c b/dlls/mshtml/mutation.c index a1438debd6f..845c189f98b 100644 --- a/dlls/mshtml/mutation.c +++ b/dlls/mshtml/mutation.c @@ -314,7 +314,7 @@ static nsresult run_end_load(HTMLDocumentNode *This, nsISupports *arg1, nsISuppo
if(This->window == window) { window->dom_interactive_time = get_time_stamp(); - set_ready_state(This->outer_window, READYSTATE_INTERACTIVE); + set_ready_state(This->window->base.outer_window, READYSTATE_INTERACTIVE); } IHTMLWindow2_Release(&window->base.IHTMLWindow2_iface); return NS_OK; diff --git a/dlls/mshtml/nsevents.c b/dlls/mshtml/nsevents.c index 8c6631626d1..84c06f6fe0a 100644 --- a/dlls/mshtml/nsevents.c +++ b/dlls/mshtml/nsevents.c @@ -336,7 +336,7 @@ static nsresult handle_load(HTMLDocumentNode *doc, nsIDOMEvent *event)
TRACE("(%p)\n", doc);
- if(!doc->outer_window) + if(!doc->window || !doc->window->base.outer_window) return NS_ERROR_FAILURE; if(doc->doc_obj && doc->doc_obj->doc_node == doc) { doc_obj = doc->doc_obj; @@ -348,7 +348,7 @@ static nsresult handle_load(HTMLDocumentNode *doc, nsIDOMEvent *event) handle_docobj_load(doc_obj);
doc->window->dom_complete_time = get_time_stamp(); - set_ready_state(doc->outer_window, READYSTATE_COMPLETE); + set_ready_state(doc->window->base.outer_window, READYSTATE_COMPLETE);
if(doc_obj) { if(doc_obj->view_sink) @@ -358,9 +358,9 @@ static nsresult handle_load(HTMLDocumentNode *doc, nsIDOMEvent *event)
update_title(doc_obj);
- if(doc_obj->doc_object_service && !(doc->outer_window->load_flags & BINDING_REFRESH)) + if(doc_obj->doc_object_service && !(doc->window->base.outer_window->load_flags & BINDING_REFRESH)) IDocObjectService_FireDocumentComplete(doc_obj->doc_object_service, - &doc->outer_window->base.IHTMLWindow2_iface, 0); + &doc->window->base.outer_window->base.IHTMLWindow2_iface, 0);
IUnknown_Release(doc_obj->outer_unk); } @@ -516,7 +516,7 @@ static nsIDOMEventTarget *get_default_document_target(HTMLDocumentNode *doc) nsISupports *target_iface; nsresult nsres;
- target_iface = doc->window ? (nsISupports*)doc->outer_window->nswindow : (nsISupports*)doc->dom_document; + target_iface = doc->window && doc->window->base.outer_window ? (nsISupports*)doc->window->base.outer_window->nswindow : (nsISupports*)doc->dom_document; nsres = nsISupports_QueryInterface(target_iface, &IID_nsIDOMEventTarget, (void**)&target); return NS_SUCCEEDED(nsres) ? target : NULL; } diff --git a/dlls/mshtml/olecmd.c b/dlls/mshtml/olecmd.c index 76ed84341cf..650c44c9d2b 100644 --- a/dlls/mshtml/olecmd.c +++ b/dlls/mshtml/olecmd.c @@ -490,10 +490,10 @@ static HRESULT exec_refresh(HTMLDocumentNode *doc, DWORD nCmdexecopt, VARIANT *p } }
- if(!doc->outer_window) + if(!doc->window || !doc->window->base.outer_window) return E_UNEXPECTED;
- return reload_page(doc->outer_window); + return reload_page(doc->window->base.outer_window); }
static HRESULT exec_stop(HTMLDocumentNode *doc, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut) diff --git a/dlls/mshtml/pluginhost.c b/dlls/mshtml/pluginhost.c index f910600de18..5f9e3588239 100644 --- a/dlls/mshtml/pluginhost.c +++ b/dlls/mshtml/pluginhost.c @@ -2227,12 +2227,12 @@ static HRESULT WINAPI PHServiceProvider_QueryService(IServiceProvider *iface, RE
TRACE("(%p)->(%s %s %p)\n", This, debugstr_guid(guidService), debugstr_guid(riid), ppv);
- if(!This->doc || !This->doc->outer_window) { + if(!This->doc || !This->doc->window || !This->doc->window->base.outer_window) { *ppv = NULL; return E_NOINTERFACE; }
- return IServiceProvider_QueryService(&This->doc->outer_window->base.IServiceProvider_iface, + return IServiceProvider_QueryService(&This->doc->window->base.outer_window->base.IServiceProvider_iface, guidService, riid, ppv); }
diff --git a/dlls/mshtml/secmgr.c b/dlls/mshtml/secmgr.c index 24c7ef2c817..ea53166f354 100644 --- a/dlls/mshtml/secmgr.c +++ b/dlls/mshtml/secmgr.c @@ -76,10 +76,10 @@ static HRESULT WINAPI InternetHostSecurityManager_ProcessUrlAction(IInternetHost
TRACE("(%p)->(%ld %p %ld %p %ld %lx %lx)\n", This, dwAction, pPolicy, cbPolicy, pContext, cbContext, dwFlags, dwReserved);
- if(!This->outer_window) + if(!This->window || !This->window->base.outer_window) return E_UNEXPECTED;
- url = This->outer_window->url ? This->outer_window->url : L"about:blank"; + url = This->window->base.outer_window->url ? This->window->base.outer_window->url : L"about:blank";
return IInternetSecurityManager_ProcessUrlAction(get_security_manager(), url, dwAction, pPolicy, cbPolicy, pContext, cbContext, dwFlags, dwReserved); @@ -181,10 +181,10 @@ static HRESULT WINAPI InternetHostSecurityManager_QueryCustomPolicy(IInternetHos
TRACE("(%p)->(%s %p %p %p %ld %lx)\n", This, debugstr_guid(guidKey), ppPolicy, pcbPolicy, pContext, cbContext, dwReserved);
- if(!This->outer_window) + if(!This->window || !This->window->base.outer_window) return E_UNEXPECTED;
- url = This->outer_window->url ? This->outer_window->url : L"about:blank"; + url = This->window->base.outer_window->url ? This->window->base.outer_window->url : L"about:blank";
hres = IInternetSecurityManager_QueryCustomPolicy(get_security_manager(), url, guidKey, ppPolicy, pcbPolicy, pContext, cbContext, dwReserved);
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/tests/events.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/dlls/mshtml/tests/events.c b/dlls/mshtml/tests/events.c index 4b775ceb8b8..4732236c52c 100644 --- a/dlls/mshtml/tests/events.c +++ b/dlls/mshtml/tests/events.c @@ -3320,6 +3320,7 @@ static void test_window_refs(IHTMLDocument2 *doc) hres = IHTMLXMLHttpRequestFactory_create(xhr_factory, &xhr); ok(hres == S_OK, "create failed: %08lx\n", hres); IHTMLXMLHttpRequestFactory_Release(xhr_factory); + IHTMLXMLHttpRequest_Release(xhr);
hres = IHTMLImageElementFactory_create(image_factory, vempty, vempty, &img_elem); ok(hres == S_OK, "create failed: %08lx\n", hres);
Well nevermind, I removed that patch for the moment to get this going. If you were reviewing it, I did not mean to waste your time—I will happily send it after this MR, just let me know if you want/changed your mind please.
The goal of that patch was never to change any existing behavior, except for the 3 cases **I tested** (and thus were "fixed" by it). BTW would you have felt more comfortable if I introduced a new `outer_window` field in the inner window without touching the base's and only using it in the 3 cases I tested for, and then merged it with base.outer_window in a separate patch **as a no-op**? That was basically my intent after all.
Anyway do let me know if anything changed so I can send it after this MR at some point, even after code freeze if that's fine.
This is still not reviewable in its current form. Neither I nor you can know what's the correct solution without doing the research. Saying that you will do the research only if I promise to accept one or another patch just doesn't make sense. It all depends on outcome of the research; until we have enough information we need to keep it open minded. Claiming that it's not needed because you're interested only in a few random tests also doesn't make sense when you change data structures used module-wide (it's even worse when tests themselves are questionable).
Doing code changes like that is easy, the hard part if figuring how to do that. It's unfair to skip the hard part, refuse to do it when asked and complain that the reviewer doesn't do it for you. It's supposed to be author's responsibility.
Anyway, I did that just so we can move forwards, see !4574. What I found is:
- On IE9+ it's not even allowed to touch detached document, not even compare it to anything. - In old IE mode any attempt to call such document is an error. - In old IE mode, detached document returns true when it's compared to current document, but still fails on any attempt to call it (unlike the current document).
Conclusions: - Arguments like "I need to get it committed because it would be hard to debug if something needs it" are pointless, web pages simply have no way of depending on what you did. - Weird crashes observed are probably a by-product of implementation of old IE modes in native; although those APIs are exposed to C it seems that they are just broken there, so trying to read too much out of it is pointless. - We should probably just error-out somewhere in JS binding layer. That's not a task for now; adding some checks to C variant is still not wrong (they are exposed with C interfaces after all), so that's what I did for now. - Storing outer window for longer than needed is not justified.
I hope that explains you why skipping proper research is not a good idea.
On Fri Dec 1 19:13:35 2023 +0000, Jacek Caban wrote:
This is still not reviewable in its current form. Neither I nor you can know what's the correct solution without doing the research. Saying that you will do the research only if I promise to accept one or another patch just doesn't make sense. It all depends on outcome of the research; until we have enough information we need to keep it open minded. Claiming that it's not needed because you're interested only in a few random tests also doesn't make sense when you change data structures used module-wide (it's even worse when tests themselves are questionable). Doing code changes like that is easy, the hard part if figuring how to do that. It's unfair to skip the hard part, refuse to do it when asked and complain that the reviewer doesn't do it for you. It's supposed to be author's responsibility. Anyway, I did that just so we can move forwards, see !4574. What I found is:
- On IE9+ it's not even allowed to touch detached document, not even
compare it to anything.
- In old IE mode any attempt to call such document is an error.
- In old IE mode, detached document returns true when it's compared to
current document, but still fails on any attempt to call it (unlike the current document). Conclusions:
- Arguments like "I need to get it committed because it would be hard to
debug if something needs it" are pointless, web pages simply have no way of depending on what you did.
- Weird crashes observed are probably a by-product of implementation of
old IE modes in native; although those APIs are exposed to C it seems that they are just broken there, so trying to read too much out of it is pointless.
- We should probably just error-out somewhere in JS binding layer.
That's not a task for now; adding some checks to C variant is still not wrong (they are exposed with C interfaces after all), so that's what I did for now.
- Storing outer window for longer than needed is not justified.
I hope that explains you why skipping proper research is not a good idea.
I understand your points, but I'm unsure how that affects the last push? I got rid of the patch that changes outer windows or keeps their refs around for longer, the other patches that are still not in !4574 were definitely fine (and even what you suggested, btw). If not, which one do you think is "not reviewable"?
The only one that comes to my mind is the `doc->outer_window` change but, it's currently broken because it **does** keep ref to the outer window for "longer than it should" (i.e. goes against what you just said), and even worse it does not even hold any sort of ref, so it can access invalid memory.
So all my patch does is make it become NULL when the inner window is detached, isn't that what you suggested?!
The storage event patch, again, just does what you suggested: it checks if we're detached and skips sending the event altogether (I did put a FIXME comment, but that's just a comment…).
Can you please tell me which patch is so wrong now?
On Tue Nov 28 14:17:15 2023 +0000, Gabriel Ivăncescu wrote:
Resetting the point to NULL is the same as using the `doc->window->base.outer_window`, which has potential for a lot more regressions (I don't mean the test). How is that better?!? I don't know why you think this is so risky; as mentioned in the MR's message, those are the only things that would be affected, and they're all either fixed or handled (handled means same behavior as before). I spent time carefully reviewing them, I'd like that not to be a waste and just dismissed like that. Sure I might have missed some, but it's pretty unlikely. I also tested real world apps and it seemed fine. I was hoping a review to "double check" it would provide the extra eyes on it, instead of being dismissed, even though it's correct. Also another argument for it is that, since I suspect it will have to be fixed properly at some point, the sooner we do it, the easier it will be to review, which is now. The more complicated mshtml becomes (necessarily, to implement new features), the harder it will be to revamp this. Why not do it now? It just seems to me that you dismiss it because of potential regressions without actually analyzing what could cause them at all, since my goal with this patch and the MR message was definitely to keep same behavior as before *except* in places where I fixed it (and mentioned in the message). *If* that's not the case everywhere I'd like to know, too, but I did carefully review it. Would you please reconsider?
Resetting the point to NULL is the same as using the `doc->window->base.outer_window`, which has potential for a lot more regressions (I don't mean the test). How is that better?!?
I don't know why you think this is so risky; as mentioned in the MR's message, those are the only things that would be affected, and they're all either fixed or handled (handled means same behavior as before). I spent time carefully reviewing them, I'd like that not to be a waste and just dismissed like that.
Sure I might have missed some, but it's pretty unlikely. I also tested real world apps and it seemed fine. I was hoping a review to "double check" it would provide the extra eyes on it, instead of being dismissed, even though it's correct.
Also another argument for it is that, since I suspect it will have to be fixed properly at some point, the sooner we do it, the easier it will be to review, which is now. The more complicated mshtml becomes (necessarily, to implement new features), the harder it will be to revamp this. Why not do it now?
It just seems to me that you dismiss it because of potential regressions without actually analyzing what could cause them at all, since my goal with this patch and the MR message was definitely to keep same behavior as before *except* in places where I fixed it (and mentioned in the message). *If* that's not the case everywhere I'd like to know, too, but I did carefully review it. Would you please reconsider?
Well as I said, I can easily just get rid of the tests and do the right thing with a comment. Silently dropping events sounds like a bad idea to me, it will make it hard to debug if something broken ever depends on it. And it's not like it's more code, either.
On Sun Dec 3 10:28:27 2023 +0000, Jacek Caban wrote:
The more I look at it the more I'm convinced that the change to keep outer window reference is not worth it. Storage events seem just outright broken on native, so that's not a good reason. Looking at Gecko, I can see that it does what we currently do and resets outer window pointer from inner window and document when inner window changes. It means that whatever we do on Wine side, everything that depends on Gecko will still not "work". The change is also quite invasive. It changes a meaning of pointers that are used module-wide, so there is some risk associated with it and the motivation seems questionable to me. Why do you need that in the first place? This is not something you've actually seen mattering for real-world use case, right? Another thing about it is that it's likely to hide some problems in the future. Resetting outer pointer is nice to have a clear cut when inner window is no longer valid. It's not a strong argument, if we really have a reason to change it, we may, but I'd like to know the reason.
Well that's why I wanted it before code freeze, so any possible regressions are detected now. Isn't that the point?
For storage events, yeah I can easily get rid of the test and just keep the current "correct" behavior with a comment. I'd rather keep that than silently drop events (or even if it's logged, it's not that obvious), because that's 1) incorrect and 2) it's extremely hard to debug if something broken ever depends on it. Plus, it's not like sending the events is extra code than silently dropping them, most of the patch is in the tests.
As for the "hide problems in the future", I actually think the exact opposite. Right now, we use the document's outer_window in same way, except it's completely broken and can access invalid memory if the outer window happens to die, which would be very hard to debug (especially considering most apps using mshtml are bloated and slow with millions of frameworks).
What problem would this hide? The things that *are* different than before (e.g. parentWindow), are tested so they're fixed and correct, with the others being same as before, except not randomly crashing in some cases.
Maybe it's not by itself a strong argument, but outer_window on document is now just simply broken and I'd like to fix that before the code freeze.
On Tue Nov 28 14:20:45 2023 +0000, Gabriel Ivăncescu wrote:
changed this line in [version 4 of the diff](/wine/wine/-/merge_requests/4380/diffs?diff_id=86488&start_sha=b60efcb09182cf569b930b34cfaa5024286e2365#56657b1594797eadb6d151cd27b78598dd3cafc0_6520_6495)
Do you mean crash on native? I mean it's known to be full of bugs and security exploits, to the point of becoming a meme. I could test it if I can use it from JS (actually, can't event handlers still be called after navigation on the old doc/window?), because it would be a silent "failure" or event firing which would be insanely hard to debug otherwise, especially since you can see event handlers are registered and all.
I wouldn't mind trying to test this out, even if it doesn't end up as proper wine tests, I just don't want it to be a waste of time, like it feels right now, even though I was expecting matching native behavior (and fixing potential memory hazards) to be a goal.
On Fri Dec 1 19:13:35 2023 +0000, Gabriel Ivăncescu wrote:
I understand your points, but I'm unsure how that affects the last push? I got rid of the patch that changes outer windows or keeps their refs around for longer, the other patches that are still not in !4574 were definitely fine (and even what you suggested, btw). If not, which one do you think is "not reviewable"? The only one that comes to my mind is the `doc->outer_window` change but, it's currently broken because it **does** keep ref to the outer window for "longer than it should" (i.e. goes against what you just said), and even worse it does not even hold any sort of ref, so it can access invalid memory. So all my patch does is make it become NULL when the inner window is detached, isn't that what you suggested?! The storage event patch, again, just does what you suggested: it checks if we're detached and skips sending the event altogether (I did put a FIXME comment, but that's just a comment…). Can you please tell me which patch is so wrong now?
The latest push had the same problem as previous ones: it lacked proper justification based on an analyze. Now that I filled that gap for you, we can move forward. !4574 is not a complete solution, more patches are still needed, please rebase and self re-review taking above into consideration. The patch removing outer_window could be split and misses a number of NULL checks.
On Mon Dec 4 13:31:52 2023 +0000, Jacek Caban wrote:
The latest push had the same problem as previous ones: it lacked proper justification based on an analyze. Now that I filled that gap for you, we can move forward. !4574 is not a complete solution, more patches are still needed, please rebase and self re-review taking above into consideration. The patch removing outer_window could be split and misses a number of NULL checks.
I removed that patch for now, I'm looking what to do with it in the meantime and split it (I wish you'd say this from the beginning), but I don't think "avoiding invalid memory access" is lack of a proper justification though, even if the reason was different. I didn't add NULL checks because it didn't have them before, though, so I just wanted to keep same behavior and make it easier to review.
BTW sorry about the comment spam, those are old emails I sent long ago but the email bridge decided to post them now?!?