Module: wine Branch: master Commit: 08485aeb48d6e70625e0d11ea29733a17360fc83 URL: http://source.winehq.org/git/wine.git/?a=commit;h=08485aeb48d6e70625e0d11ea2... Author: Jacek Caban <jacek(a)codeweavers.com> Date: Fri Oct 19 11:56:59 2012 +0200 mshtml: Properly handle OOM errors in task.c (coverity). --- dlls/mshtml/htmlwindow.c | 5 ++- dlls/mshtml/mshtml_private.h | 4 +- dlls/mshtml/navigate.c | 13 ++++------ dlls/mshtml/nsio.c | 4 ++- dlls/mshtml/persist.c | 10 +++++--- dlls/mshtml/task.c | 52 ++++++++++++++++++++++++++++++++++------- 6 files changed, 62 insertions(+), 26 deletions(-) diff --git a/dlls/mshtml/htmlwindow.c b/dlls/mshtml/htmlwindow.c index 59b02ab..dede0a7 100644 --- a/dlls/mshtml/htmlwindow.c +++ b/dlls/mshtml/htmlwindow.c @@ -1544,6 +1544,7 @@ static HRESULT window_set_timer(HTMLInnerWindow *This, VARIANT *expr, LONG msec, BOOL interval, LONG *timer_id) { IDispatch *disp = NULL; + HRESULT hres; switch(V_VT(expr)) { case VT_DISPATCH: @@ -1563,10 +1564,10 @@ static HRESULT window_set_timer(HTMLInnerWindow *This, VARIANT *expr, LONG msec, if(!disp) return E_FAIL; - *timer_id = set_task_timer(This, msec, interval, disp); + hres = set_task_timer(This, msec, interval, disp, timer_id); IDispatch_Release(disp); - return S_OK; + return hres; } static HRESULT WINAPI HTMLWindow3_setTimeout(IHTMLWindow3 *iface, VARIANT *expression, LONG msec, diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index c54a865..f94f226 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -977,10 +977,10 @@ thread_data_t *get_thread_data(BOOL) DECLSPEC_HIDDEN; HWND get_thread_hwnd(void) DECLSPEC_HIDDEN; LONG get_task_target_magic(void) DECLSPEC_HIDDEN; -void push_task(task_t*,task_proc_t,task_proc_t,LONG) DECLSPEC_HIDDEN; +HRESULT push_task(task_t*,task_proc_t,task_proc_t,LONG) DECLSPEC_HIDDEN; void remove_target_tasks(LONG) DECLSPEC_HIDDEN; -DWORD set_task_timer(HTMLInnerWindow*,DWORD,BOOL,IDispatch*) DECLSPEC_HIDDEN; +HRESULT set_task_timer(HTMLInnerWindow*,DWORD,BOOL,IDispatch*,LONG*) DECLSPEC_HIDDEN; HRESULT clear_task_timer(HTMLInnerWindow*,BOOL,DWORD) DECLSPEC_HIDDEN; const char *debugstr_variant(const VARIANT*) DECLSPEC_HIDDEN; diff --git a/dlls/mshtml/navigate.c b/dlls/mshtml/navigate.c index 8554ddb..f1f0f98 100644 --- a/dlls/mshtml/navigate.c +++ b/dlls/mshtml/navigate.c @@ -1437,8 +1437,7 @@ static HRESULT async_stop_request(nsChannelBSC *This) IBindStatusCallback_AddRef(&This->bsc.IBindStatusCallback_iface); task->bsc = This; - push_task(&task->header, stop_request_proc, stop_request_task_destr, This->bsc.window->task_magic); - return S_OK; + return push_task(&task->header, stop_request_proc, stop_request_task_destr, This->bsc.window->task_magic); } static void handle_navigation_error(nsChannelBSC *This, DWORD result) @@ -1798,8 +1797,7 @@ HRESULT async_start_doc_binding(HTMLOuterWindow *window, HTMLInnerWindow *pendin task->pending_window = pending_window; IHTMLWindow2_AddRef(&pending_window->base.IHTMLWindow2_iface); - push_task(&task->header, start_doc_binding_proc, start_doc_binding_task_destr, pending_window->task_magic); - return S_OK; + return push_task(&task->header, start_doc_binding_proc, start_doc_binding_task_destr, pending_window->task_magic); } void abort_window_bindings(HTMLInnerWindow *window) @@ -2105,8 +2103,7 @@ HRESULT super_navigate(HTMLOuterWindow *window, IUri *uri, const WCHAR *headers, task->window = window; task->bscallback = bsc; task->mon = mon; - push_task(&task->header, navigate_proc, navigate_task_destr, window->task_magic); - + hres = push_task(&task->header, navigate_proc, navigate_task_destr, window->task_magic); }else { navigate_javascript_task_t *task; @@ -2124,10 +2121,10 @@ HRESULT super_navigate(HTMLOuterWindow *window, IUri *uri, const WCHAR *headers, IUri_AddRef(uri); task->window = window; task->uri = uri; - push_task(&task->header, navigate_javascript_proc, navigate_javascript_task_destr, window->task_magic); + hres = push_task(&task->header, navigate_javascript_proc, navigate_javascript_task_destr, window->task_magic); } - return S_OK; + return hres; } HRESULT navigate_new_window(HTMLOuterWindow *window, IUri *uri, const WCHAR *name, IHTMLWindow2 **ret) diff --git a/dlls/mshtml/nsio.c b/dlls/mshtml/nsio.c index cf71ec5..6e63244 100644 --- a/dlls/mshtml/nsio.c +++ b/dlls/mshtml/nsio.c @@ -1013,7 +1013,9 @@ static nsresult async_open(nsChannel *This, HTMLOuterWindow *window, BOOL is_doc task->window = window->base.inner_window; task->bscallback = bscallback; - push_task(&task->header, start_binding_proc, start_binding_task_destr, window->base.inner_window->task_magic); + hres = push_task(&task->header, start_binding_proc, start_binding_task_destr, window->base.inner_window->task_magic); + if(FAILED(hres)) + return NS_ERROR_OUT_OF_MEMORY; } return NS_OK; diff --git a/dlls/mshtml/persist.c b/dlls/mshtml/persist.c index b518b56..b68f79a 100644 --- a/dlls/mshtml/persist.c +++ b/dlls/mshtml/persist.c @@ -388,16 +388,18 @@ HRESULT set_moniker(HTMLDocument *This, IMoniker *mon, IBindCtx *pibc, nsChannel task = heap_alloc(sizeof(docobj_task_t)); task->doc = This->doc_obj; - push_task(&task->header, set_progress_proc, NULL, This->doc_obj->basedoc.task_magic); + hres = push_task(&task->header, set_progress_proc, NULL, This->doc_obj->basedoc.task_magic); + if(FAILED(hres)) { + CoTaskMemFree(url); + return hres; + } } download_task = heap_alloc(sizeof(download_proc_task_t)); download_task->doc = This->doc_obj; download_task->set_download = set_download; download_task->url = url; - push_task(&download_task->header, set_downloading_proc, set_downloading_task_destr, This->doc_obj->basedoc.task_magic); - - return S_OK; + return push_task(&download_task->header, set_downloading_proc, set_downloading_task_destr, This->doc_obj->basedoc.task_magic); } void set_ready_state(HTMLOuterWindow *window, READYSTATE readystate) diff --git a/dlls/mshtml/task.c b/dlls/mshtml/task.c index 0fea1ca..bb8b4e0 100644 --- a/dlls/mshtml/task.c +++ b/dlls/mshtml/task.c @@ -20,6 +20,7 @@ #include <stdarg.h> #include <stdio.h> +#include <assert.h> #define COBJMACROS @@ -52,9 +53,18 @@ static void default_task_destr(task_t *task) heap_free(task); } -void push_task(task_t *task, task_proc_t proc, task_proc_t destr, LONG magic) +HRESULT push_task(task_t *task, task_proc_t proc, task_proc_t destr, LONG magic) { - thread_data_t *thread_data = get_thread_data(TRUE); + thread_data_t *thread_data; + + thread_data = get_thread_data(TRUE); + if(!thread_data) { + if(destr) + destr(task); + else + heap_free(task); + return E_OUTOFMEMORY; + } task->target_magic = magic; task->proc = proc; @@ -69,13 +79,19 @@ void push_task(task_t *task, task_proc_t proc, task_proc_t destr, LONG magic) thread_data->task_queue_tail = task; PostMessageW(thread_data->thread_hwnd, WM_PROCESSTASK, 0, 0); + return S_OK; } static task_t *pop_task(void) { - thread_data_t *thread_data = get_thread_data(TRUE); - task_t *task = thread_data->task_queue_head; + thread_data_t *thread_data; + task_t *task; + thread_data = get_thread_data(FALSE); + if(!thread_data) + return NULL; + + task = thread_data->task_queue_head; if(!task) return NULL; @@ -163,15 +179,22 @@ static BOOL queue_timer(thread_data_t *thread_data, task_timer_t *timer) return FALSE; } -DWORD set_task_timer(HTMLInnerWindow *window, DWORD msec, BOOL interval, IDispatch *disp) +HRESULT set_task_timer(HTMLInnerWindow *window, DWORD msec, BOOL interval, IDispatch *disp, LONG *id) { - thread_data_t *thread_data = get_thread_data(TRUE); + thread_data_t *thread_data; task_timer_t *timer; DWORD tc = GetTickCount(); static DWORD id_cnt = 0x20000000; + thread_data = get_thread_data(TRUE); + if(!thread_data) + return E_OUTOFMEMORY; + timer = heap_alloc(sizeof(task_timer_t)); + if(!timer) + return E_OUTOFMEMORY; + timer->id = id_cnt++; timer->window = window; timer->time = tc + msec; @@ -184,7 +207,8 @@ DWORD set_task_timer(HTMLInnerWindow *window, DWORD msec, BOOL interval, IDispat if(queue_timer(thread_data, timer)) SetTimer(thread_data->thread_hwnd, TIMER_ID, msec, NULL); - return timer->id; + *id = timer->id; + return S_OK; } HRESULT clear_task_timer(HTMLInnerWindow *window, BOOL interval, DWORD id) @@ -228,13 +252,16 @@ static void call_timer_disp(IDispatch *disp) static LRESULT process_timer(void) { - thread_data_t *thread_data = get_thread_data(TRUE); + thread_data_t *thread_data; IDispatch *disp; DWORD tc; task_timer_t *timer; TRACE("\n"); + thread_data = get_thread_data(FALSE); + assert(thread_data != NULL); + while(!list_empty(&thread_data->timer_list)) { timer = LIST_ENTRY(list_head(&thread_data->timer_list), task_timer_t, entry); @@ -311,7 +338,11 @@ static HWND create_thread_hwnd(void) HWND get_thread_hwnd(void) { - thread_data_t *thread_data = get_thread_data(TRUE); + thread_data_t *thread_data; + + thread_data = get_thread_data(TRUE); + if(!thread_data) + return NULL; if(!thread_data->thread_hwnd) thread_data->thread_hwnd = create_thread_hwnd(); @@ -341,6 +372,9 @@ thread_data_t *get_thread_data(BOOL create) thread_data = TlsGetValue(mshtml_tls); if(!thread_data && create) { thread_data = heap_alloc_zero(sizeof(thread_data_t)); + if(!thread_data) + return NULL; + TlsSetValue(mshtml_tls, thread_data); list_init(&thread_data->timer_list); }