Jacek Caban : mshtml: Properly handle OOM errors in task.c (coverity).

Alexandre Julliard julliard at winehq.org
Fri Oct 19 13:33:53 CDT 2012


Module: wine
Branch: master
Commit: 08485aeb48d6e70625e0d11ea29733a17360fc83
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=08485aeb48d6e70625e0d11ea29733a17360fc83

Author: Jacek Caban <jacek at 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);
     }




More information about the wine-cvs mailing list