From: Gabriel Ivăncescu gabrielopcode@gmail.com
Accessing the outer window from an inner window (such as its event target) should always be valid, even if the outer window isn't currently referring to the same inner window, because it's supposed to proxy all requests to the "current" inner window.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlwindow.c | 42 ++++++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 15 deletions(-)
diff --git a/dlls/mshtml/htmlwindow.c b/dlls/mshtml/htmlwindow.c index 3fc798287bc..3783f246cae 100644 --- a/dlls/mshtml/htmlwindow.c +++ b/dlls/mshtml/htmlwindow.c @@ -134,12 +134,6 @@ static void detach_inner_window(HTMLInnerWindow *window) abort_window_bindings(window); remove_target_tasks(window->task_magic); release_script_hosts(window); - window->base.outer_window = NULL; - - if(outer_window && outer_window->base.inner_window == window) { - outer_window->base.inner_window = NULL; - IHTMLWindow2_Release(&window->base.IHTMLWindow2_iface); - } }
static inline HTMLWindow *impl_from_IHTMLWindow2(IHTMLWindow2 *iface) @@ -3930,6 +3924,8 @@ static void HTMLWindow_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCa HTMLOuterWindow *child;
traverse_event_target(&This->event_target, cb); + if(This->base.outer_window) + note_cc_edge((nsISupports*)&This->base.outer_window->base.IHTMLWindow2_iface, "outer_window", cb); LIST_FOR_EACH_ENTRY(child, &This->children, HTMLOuterWindow, sibling_entry) note_cc_edge((nsISupports*)&child->base.IHTMLWindow2_iface, "child", cb); if(This->doc) @@ -3966,6 +3962,11 @@ static void HTMLWindow_unlink(DispatchEx *dispex) unlink_ref(&This->console); detach_inner_window(This);
+ if(This->base.outer_window) { + HTMLOuterWindow *outer_window = This->base.outer_window; + This->base.outer_window = NULL; + IHTMLWindow2_Release(&outer_window->base.IHTMLWindow2_iface); + } if(This->doc) { HTMLDocumentNode *doc = This->doc; This->doc->window = NULL; @@ -4349,16 +4350,19 @@ static nsresult NSAPI outer_window_unlink(void *p) } if(window->pending_window) { HTMLInnerWindow *pending_window = window->pending_window; - abort_window_bindings(pending_window); - pending_window->base.outer_window = NULL; window->pending_window = NULL; + detach_inner_window(pending_window); IHTMLWindow2_Release(&pending_window->base.IHTMLWindow2_iface); }
set_current_mon(window, NULL, 0); set_current_uri(window, NULL); - if(window->base.inner_window) - detach_inner_window(window->base.inner_window); + if(window->base.inner_window) { + HTMLInnerWindow *inner_window = window->base.inner_window; + window->base.inner_window = NULL; + detach_inner_window(inner_window); + IHTMLWindow2_Release(&inner_window->base.IHTMLWindow2_iface); + } if(window->location) { HTMLLocation *location = window->location; window->location = NULL; @@ -4434,6 +4438,7 @@ static HRESULT create_inner_window(HTMLOuterWindow *outer_window, IMoniker *mon,
window->base.outer_window = outer_window; window->base.inner_window = window; + IHTMLWindow2_AddRef(&outer_window->base.IHTMLWindow2_iface);
EventTarget_Init(&window->event_target, &HTMLWindow_dispex, COMPAT_MODE_NONE);
@@ -4517,7 +4522,6 @@ HRESULT create_pending_window(HTMLOuterWindow *outer_window, nsChannelBSC *chann
if(outer_window->pending_window) { abort_window_bindings(outer_window->pending_window); - outer_window->pending_window->base.outer_window = NULL; IHTMLWindow2_Release(&outer_window->pending_window->base.IHTMLWindow2_iface); }
@@ -4562,8 +4566,12 @@ void set_window_uninitialized(HTMLOuterWindow *window, HTMLDocumentNode *doc_nod window->pending_window->doc->doc_obj = NULL; window->pending_window->doc->cp_container.forward_container = NULL;
- if(window->base.inner_window) - detach_inner_window(window->base.inner_window); + if(window->base.inner_window) { + HTMLInnerWindow *inner_window = window->base.inner_window; + window->base.inner_window = NULL; + detach_inner_window(inner_window); + IHTMLWindow2_Release(&inner_window->base.IHTMLWindow2_iface); + } window->base.inner_window = window->pending_window; window->pending_window = NULL; } @@ -4600,8 +4608,12 @@ HRESULT update_window_doc(HTMLInnerWindow *window) return S_OK; }
- if(outer_window->base.inner_window) - detach_inner_window(outer_window->base.inner_window); + if(outer_window->base.inner_window) { + HTMLInnerWindow *inner_window = outer_window->base.inner_window; + outer_window->base.inner_window = NULL; + detach_inner_window(inner_window); + IHTMLWindow2_Release(&inner_window->base.IHTMLWindow2_iface); + } outer_window->base.inner_window = window; outer_window->pending_window = NULL;