From: Gabriel Ivăncescu gabrielopcode@gmail.com
It's possible for it to get detached while processing an external callback notification, such as when navigation happens during it.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/mutation.c | 5 +++-- dlls/mshtml/navigate.c | 12 ++++++++++-- dlls/mshtml/persist.c | 8 ++++++-- 3 files changed, 19 insertions(+), 6 deletions(-)
diff --git a/dlls/mshtml/mutation.c b/dlls/mshtml/mutation.c index 79850447f64..74424bb8afc 100644 --- a/dlls/mshtml/mutation.c +++ b/dlls/mshtml/mutation.c @@ -296,6 +296,7 @@ static nsresult run_end_load(HTMLDocumentNode *This, nsISupports *arg1, nsISuppo if(!This->doc_obj) return NS_OK; IUnknown_AddRef(This->doc_obj->outer_unk); + IHTMLWindow2_AddRef(&This->window->base.IHTMLWindow2_iface);
if(This == This->doc_obj->doc_node) { /* @@ -310,6 +311,7 @@ static nsresult run_end_load(HTMLDocumentNode *This, nsISupports *arg1, nsISuppo This->window->performance_timing->dom_interactive_time = get_time_stamp(); set_ready_state(This->outer_window, READYSTATE_INTERACTIVE);
+ IHTMLWindow2_Release(&This->window->base.IHTMLWindow2_iface); IUnknown_Release(This->doc_obj->outer_unk); return NS_OK; } @@ -367,14 +369,13 @@ static nsresult run_insert_script(HTMLDocumentNode *doc, nsISupports *script_ifa free(iter); }
- IHTMLWindow2_Release(&window->base.IHTMLWindow2_iface); - if(nsparser) { window->parser_callback_cnt--; nsIParser_EndEvaluatingParserInsertedScript(nsparser); nsIParser_Release(nsparser); }
+ IHTMLWindow2_Release(&window->base.IHTMLWindow2_iface); IHTMLScriptElement_Release(&script_elem->IHTMLScriptElement_iface);
return NS_OK; diff --git a/dlls/mshtml/navigate.c b/dlls/mshtml/navigate.c index 68fd8a796c0..e7575790a8a 100644 --- a/dlls/mshtml/navigate.c +++ b/dlls/mshtml/navigate.c @@ -1419,8 +1419,11 @@ static void stop_request_task_destr(task_t *_task)
static HRESULT async_stop_request(nsChannelBSC *This) { + HTMLInnerWindow *window = This->bsc.window; stop_request_task_t *task; + HRESULT hres;
+ IHTMLWindow2_AddRef(&window->base.IHTMLWindow2_iface); if(!This->bsc.read) { TRACE("No data read, calling OnStartRequest\n"); on_start_nsrequest(This); @@ -1433,7 +1436,9 @@ static HRESULT async_stop_request(nsChannelBSC *This) IBindStatusCallback_AddRef(&This->bsc.IBindStatusCallback_iface); task->bsc = This;
- return push_task(&task->header, stop_request_proc, stop_request_task_destr, This->bsc.window->task_magic); + hres = push_task(&task->header, stop_request_proc, stop_request_task_destr, window->task_magic); + IHTMLWindow2_Release(&window->base.IHTMLWindow2_iface); + return hres; }
static void handle_navigation_error(nsChannelBSC *This, DWORD result) @@ -2069,6 +2074,7 @@ typedef struct { static void navigate_javascript_proc(task_t *_task) { navigate_javascript_task_t *task = (navigate_javascript_task_t*)_task; + HTMLInnerWindow *inner_window = task->window->base.inner_window; HTMLOuterWindow *window = task->window; HTMLDocumentObj *doc = NULL; BSTR code = NULL; @@ -2080,6 +2086,7 @@ static void navigate_javascript_proc(task_t *_task) doc = window->browser->doc; IUnknown_AddRef(doc->outer_unk); } + IHTMLWindow2_AddRef(&inner_window->base.IHTMLWindow2_iface);
hres = IUri_GetPath(task->uri, &code); if(hres != S_OK) { @@ -2097,7 +2104,7 @@ static void navigate_javascript_proc(task_t *_task) set_download_state(doc, 1);
V_VT(&v) = VT_EMPTY; - hres = exec_script(window->base.inner_window, code, L"jscript", &v); + hres = exec_script(inner_window, code, L"jscript", &v); SysFreeString(code); if(SUCCEEDED(hres) && V_VT(&v) != VT_EMPTY) { FIXME("javascirpt URL returned %s\n", debugstr_variant(&v)); @@ -2112,6 +2119,7 @@ static void navigate_javascript_proc(task_t *_task) }
done: + IHTMLWindow2_Release(&inner_window->base.IHTMLWindow2_iface); if(doc) IUnknown_Release(doc->outer_unk); } diff --git a/dlls/mshtml/persist.c b/dlls/mshtml/persist.c index 94b52e3a476..da9dafedfa1 100644 --- a/dlls/mshtml/persist.c +++ b/dlls/mshtml/persist.c @@ -441,20 +441,24 @@ HRESULT set_moniker(HTMLOuterWindow *window, IMoniker *mon, IUri *nav_uri, IBind
static void notif_readystate(HTMLOuterWindow *window) { + HTMLInnerWindow *inner_window = window->base.inner_window; DOMEvent *event; HRESULT hres;
window->readystate_pending = FALSE;
+ IHTMLWindow2_AddRef(&inner_window->base.IHTMLWindow2_iface); + if(is_main_content_window(window)) call_property_onchanged(&window->browser->doc->cp_container, DISPID_READYSTATE);
- hres = create_document_event(window->base.inner_window->doc, EVENTID_READYSTATECHANGE, &event); + hres = create_document_event(inner_window->doc, EVENTID_READYSTATECHANGE, &event); if(SUCCEEDED(hres)) { event->no_event_obj = TRUE; - dispatch_event(&window->base.inner_window->doc->node.event_target, event); + dispatch_event(&inner_window->doc->node.event_target, event); IDOMEvent_Release(&event->IDOMEvent_iface); } + IHTMLWindow2_Release(&inner_window->base.IHTMLWindow2_iface);
if(window->frame_element) { hres = create_document_event(window->frame_element->element.node.doc, EVENTID_READYSTATECHANGE, &event);