mirror of
git://source.winehq.org/git/wine.git
synced 2024-09-16 03:46:49 +00:00
mshtml: Hold ref to inner window when calling external code.
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>
This commit is contained in:
parent
a62be201c8
commit
fbeab911c9
|
@ -292,11 +292,13 @@ static void parse_complete(HTMLDocumentObj *doc)
|
||||||
static nsresult run_end_load(HTMLDocumentNode *This, nsISupports *arg1, nsISupports *arg2)
|
static nsresult run_end_load(HTMLDocumentNode *This, nsISupports *arg1, nsISupports *arg2)
|
||||||
{
|
{
|
||||||
HTMLDocumentObj *doc_obj = This->doc_obj;
|
HTMLDocumentObj *doc_obj = This->doc_obj;
|
||||||
|
HTMLInnerWindow *window = This->window;
|
||||||
|
|
||||||
TRACE("(%p)\n", This);
|
TRACE("(%p)\n", This);
|
||||||
|
|
||||||
if(!doc_obj)
|
if(!doc_obj)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
IHTMLWindow2_AddRef(&window->base.IHTMLWindow2_iface);
|
||||||
|
|
||||||
if(This == doc_obj->doc_node) {
|
if(This == doc_obj->doc_node) {
|
||||||
/*
|
/*
|
||||||
|
@ -310,8 +312,11 @@ static nsresult run_end_load(HTMLDocumentNode *This, nsISupports *arg1, nsISuppo
|
||||||
|
|
||||||
bind_event_scripts(This);
|
bind_event_scripts(This);
|
||||||
|
|
||||||
This->window->performance_timing->dom_interactive_time = get_time_stamp();
|
if(This->window == window) {
|
||||||
set_ready_state(This->outer_window, READYSTATE_INTERACTIVE);
|
window->performance_timing->dom_interactive_time = get_time_stamp();
|
||||||
|
set_ready_state(This->outer_window, READYSTATE_INTERACTIVE);
|
||||||
|
}
|
||||||
|
IHTMLWindow2_Release(&window->base.IHTMLWindow2_iface);
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -368,14 +373,13 @@ static nsresult run_insert_script(HTMLDocumentNode *doc, nsISupports *script_ifa
|
||||||
free(iter);
|
free(iter);
|
||||||
}
|
}
|
||||||
|
|
||||||
IHTMLWindow2_Release(&window->base.IHTMLWindow2_iface);
|
|
||||||
|
|
||||||
if(nsparser) {
|
if(nsparser) {
|
||||||
window->parser_callback_cnt--;
|
window->parser_callback_cnt--;
|
||||||
nsIParser_EndEvaluatingParserInsertedScript(nsparser);
|
nsIParser_EndEvaluatingParserInsertedScript(nsparser);
|
||||||
nsIParser_Release(nsparser);
|
nsIParser_Release(nsparser);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IHTMLWindow2_Release(&window->base.IHTMLWindow2_iface);
|
||||||
IHTMLScriptElement_Release(&script_elem->IHTMLScriptElement_iface);
|
IHTMLScriptElement_Release(&script_elem->IHTMLScriptElement_iface);
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
|
@ -1419,8 +1419,11 @@ static void stop_request_task_destr(task_t *_task)
|
||||||
|
|
||||||
static HRESULT async_stop_request(nsChannelBSC *This)
|
static HRESULT async_stop_request(nsChannelBSC *This)
|
||||||
{
|
{
|
||||||
|
HTMLInnerWindow *window = This->bsc.window;
|
||||||
stop_request_task_t *task;
|
stop_request_task_t *task;
|
||||||
|
HRESULT hres;
|
||||||
|
|
||||||
|
IHTMLWindow2_AddRef(&window->base.IHTMLWindow2_iface);
|
||||||
if(!This->bsc.read) {
|
if(!This->bsc.read) {
|
||||||
TRACE("No data read, calling OnStartRequest\n");
|
TRACE("No data read, calling OnStartRequest\n");
|
||||||
on_start_nsrequest(This);
|
on_start_nsrequest(This);
|
||||||
|
@ -1433,7 +1436,9 @@ static HRESULT async_stop_request(nsChannelBSC *This)
|
||||||
IBindStatusCallback_AddRef(&This->bsc.IBindStatusCallback_iface);
|
IBindStatusCallback_AddRef(&This->bsc.IBindStatusCallback_iface);
|
||||||
task->bsc = This;
|
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)
|
static void handle_navigation_error(nsChannelBSC *This, DWORD result)
|
||||||
|
@ -2069,6 +2074,7 @@ typedef struct {
|
||||||
static void navigate_javascript_proc(task_t *_task)
|
static void navigate_javascript_proc(task_t *_task)
|
||||||
{
|
{
|
||||||
navigate_javascript_task_t *task = (navigate_javascript_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;
|
HTMLOuterWindow *window = task->window;
|
||||||
HTMLDocumentObj *doc = NULL;
|
HTMLDocumentObj *doc = NULL;
|
||||||
BSTR code = NULL;
|
BSTR code = NULL;
|
||||||
|
@ -2080,6 +2086,7 @@ static void navigate_javascript_proc(task_t *_task)
|
||||||
doc = window->browser->doc;
|
doc = window->browser->doc;
|
||||||
IUnknown_AddRef(doc->outer_unk);
|
IUnknown_AddRef(doc->outer_unk);
|
||||||
}
|
}
|
||||||
|
IHTMLWindow2_AddRef(&inner_window->base.IHTMLWindow2_iface);
|
||||||
|
|
||||||
hres = IUri_GetPath(task->uri, &code);
|
hres = IUri_GetPath(task->uri, &code);
|
||||||
if(hres != S_OK) {
|
if(hres != S_OK) {
|
||||||
|
@ -2097,7 +2104,7 @@ static void navigate_javascript_proc(task_t *_task)
|
||||||
set_download_state(doc, 1);
|
set_download_state(doc, 1);
|
||||||
|
|
||||||
V_VT(&v) = VT_EMPTY;
|
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);
|
SysFreeString(code);
|
||||||
if(SUCCEEDED(hres) && V_VT(&v) != VT_EMPTY) {
|
if(SUCCEEDED(hres) && V_VT(&v) != VT_EMPTY) {
|
||||||
FIXME("javascirpt URL returned %s\n", debugstr_variant(&v));
|
FIXME("javascirpt URL returned %s\n", debugstr_variant(&v));
|
||||||
|
@ -2112,6 +2119,7 @@ static void navigate_javascript_proc(task_t *_task)
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
|
IHTMLWindow2_Release(&inner_window->base.IHTMLWindow2_iface);
|
||||||
if(doc)
|
if(doc)
|
||||||
IUnknown_Release(doc->outer_unk);
|
IUnknown_Release(doc->outer_unk);
|
||||||
}
|
}
|
||||||
|
|
|
@ -437,20 +437,24 @@ HRESULT set_moniker(HTMLOuterWindow *window, IMoniker *mon, IUri *nav_uri, IBind
|
||||||
|
|
||||||
static void notif_readystate(HTMLOuterWindow *window)
|
static void notif_readystate(HTMLOuterWindow *window)
|
||||||
{
|
{
|
||||||
|
HTMLInnerWindow *inner_window = window->base.inner_window;
|
||||||
DOMEvent *event;
|
DOMEvent *event;
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
|
|
||||||
window->readystate_pending = FALSE;
|
window->readystate_pending = FALSE;
|
||||||
|
|
||||||
|
IHTMLWindow2_AddRef(&inner_window->base.IHTMLWindow2_iface);
|
||||||
|
|
||||||
if(is_main_content_window(window))
|
if(is_main_content_window(window))
|
||||||
call_property_onchanged(&window->browser->doc->cp_container, DISPID_READYSTATE);
|
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)) {
|
if(SUCCEEDED(hres)) {
|
||||||
event->no_event_obj = TRUE;
|
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);
|
IDOMEvent_Release(&event->IDOMEvent_iface);
|
||||||
}
|
}
|
||||||
|
IHTMLWindow2_Release(&inner_window->base.IHTMLWindow2_iface);
|
||||||
|
|
||||||
if(window->frame_element) {
|
if(window->frame_element) {
|
||||||
hres = create_document_event(window->frame_element->element.node.doc, EVENTID_READYSTATECHANGE, &event);
|
hres = create_document_event(window->frame_element->element.node.doc, EVENTID_READYSTATECHANGE, &event);
|
||||||
|
|
Loading…
Reference in a new issue