From f8499aa71acbb5608fb6243c36493d3ea3b37478 Mon Sep 17 00:00:00 2001
From: Lioncash <mathew1800@gmail.com>
Date: Mon, 15 Sep 2014 08:17:16 -0400
Subject: [PATCH] Sanitize against NULL in some free-like functions.

---
 dynamic.c                      |  3 +++
 fifo_buffer.c                  |  3 +++
 file_list.c                    |  3 +++
 gfx/d3d/d3d.cpp                | 10 ++++++++++
 gfx/d3d/render_chain.cpp       |  3 +++
 gfx/d3d/render_chain_cg.h      |  8 ++++++++
 gfx/d3d/render_chain_xdk.h     |  3 +++
 gfx/filters/2xbr.c             |  4 ++++
 gfx/filters/2xsai.c            |  4 ++++
 gfx/filters/blargg_ntsc_snes.c |  3 +++
 gfx/filters/darken.c           |  4 ++++
 gfx/filters/epx.c              |  4 ++++
 gfx/filters/lq2x.c             |  4 ++++
 gfx/filters/phosphor2x.c       |  4 ++++
 gfx/filters/scale2x.c          |  4 ++++
 gfx/filters/super2xsai.c       |  4 ++++
 gfx/filters/supereagle.c       |  4 ++++
 gfx/image/image_rpng.c         |  3 +++
 gfx/rpng/rpng.c                |  3 +++
 gfx/vg.c                       |  3 +++
 gfx/xvideo.c                   |  4 ++++
 input/gx_input.c               |  5 ++++-
 input/overlay.c                |  8 ++++++++
 input/psp_input.c              |  3 +++
 input/rwebinput_input.c        |  5 ++++-
 input/x11_input.c              |  5 ++++-
 input/xdk_xinput_input.c       |  5 ++++-
 rewind.c                       |  3 +++
 thread.c                       | 12 ++++++++++++
 29 files changed, 127 insertions(+), 4 deletions(-)

diff --git a/dynamic.c b/dynamic.c
index c80f8c7a69..7d44990284 100644
--- a/dynamic.c
+++ b/dynamic.c
@@ -182,6 +182,9 @@ bool libretro_get_system_info(const char *path,
 
 void libretro_free_system_info(struct retro_system_info *info)
 {
+   if (!info)
+      return;
+
    free((void*)info->library_name);
    free((void*)info->library_version);
    free((void*)info->valid_extensions);
diff --git a/fifo_buffer.c b/fifo_buffer.c
index 82258b389b..657697a53b 100644
--- a/fifo_buffer.c
+++ b/fifo_buffer.c
@@ -43,6 +43,9 @@ fifo_buffer_t *fifo_new(size_t size)
 
 void fifo_free(fifo_buffer_t *buffer)
 {
+   if(!buffer)
+      return;
+
    free(buffer->buffer);
    free(buffer);
 }
diff --git a/file_list.c b/file_list.c
index f28a075a18..f3aee8b7c9 100644
--- a/file_list.c
+++ b/file_list.c
@@ -84,6 +84,9 @@ void file_list_free(file_list_t *list)
 {
    size_t i;
 
+   if (!list)
+      return;
+
    for (i = 0; i < list->size; i++)
    {
       free(list->list[i].path);
diff --git a/gfx/d3d/d3d.cpp b/gfx/d3d/d3d.cpp
index 2c70586c2c..9c1a9a7f9a 100644
--- a/gfx/d3d/d3d.cpp
+++ b/gfx/d3d/d3d.cpp
@@ -717,6 +717,10 @@ static void *d3d_init(const video_info_t *info,
 static void d3d_free(void *data)
 {
    d3d_video_t *d3d = (d3d_video_t*)data;
+
+   if (!d3d)
+      return;
+
    d3d_deinitialize(d3d);
 #ifdef HAVE_OVERLAY
    d3d_free_overlays(d3d);
@@ -1342,6 +1346,9 @@ static void d3d_free_overlay(void *data, overlay_t *overlay)
 {
    d3d_video_t *d3d = (d3d_video_t*)data;
 
+   if (!d3d)
+      return;
+
    d3d_texture_free(overlay->tex);
    d3d_vertex_buffer_free(overlay->vert_buf);
 }
@@ -1351,6 +1358,9 @@ static void d3d_free_overlays(void *data)
    unsigned i;
    d3d_video_t *d3d = (d3d_video_t*)data;
 
+   if (!d3d)
+      return;
+
    for (i = 0; i < d3d->overlays.size(); i++)
       d3d_free_overlay(d3d, &d3d->overlays[i]);
    d3d->overlays.clear();
diff --git a/gfx/d3d/render_chain.cpp b/gfx/d3d/render_chain.cpp
index 4f4f787183..75e1a9bb96 100644
--- a/gfx/d3d/render_chain.cpp
+++ b/gfx/d3d/render_chain.cpp
@@ -36,6 +36,9 @@ void renderchain_free(void *data)
 {
    renderchain_t *chain = (renderchain_t*)data;
 
+   if (!chain)
+      return;
+
    renderchain_clear(chain);
    renderchain_destroy_stock_shader(chain);
    if (chain->tracker)
diff --git a/gfx/d3d/render_chain_cg.h b/gfx/d3d/render_chain_cg.h
index 53351f95eb..3665d37f88 100644
--- a/gfx/d3d/render_chain_cg.h
+++ b/gfx/d3d/render_chain_cg.h
@@ -145,6 +145,10 @@ void renderchain_set_shaders(void *data, CGprogram &fPrg, CGprogram &vPrg)
 void renderchain_destroy_stock_shader(void *data)
 {
    renderchain_t *chain = (renderchain_t*)data;
+
+   if (!chain)
+      return;
+
 #ifdef HAVE_CG
    if (chain->fStock)
       cgDestroyProgram(chain->fStock);
@@ -156,6 +160,10 @@ void renderchain_destroy_stock_shader(void *data)
 void renderchain_destroy_shader(void *data, int i)
 {
    renderchain_t *chain = (renderchain_t*)data;
+
+   if (!chain)
+      return;
+
 #ifdef HAVE_CG
    if (chain->passes[i].fPrg)
       cgDestroyProgram(chain->passes[i].fPrg);
diff --git a/gfx/d3d/render_chain_xdk.h b/gfx/d3d/render_chain_xdk.h
index a5b3bb7977..e7d33be380 100644
--- a/gfx/d3d/render_chain_xdk.h
+++ b/gfx/d3d/render_chain_xdk.h
@@ -23,6 +23,9 @@ static void renderchain_free(void *data)
 {
    d3d_video_t *chain = (d3d_video_t*)data;
 
+   if (!chain)
+      return;
+
    renderchain_clear(chain);
    //renderchain_destroy_stock_shader(chain);
 #ifndef DONT_HAVE_STATE_TRACKER
diff --git a/gfx/filters/2xbr.c b/gfx/filters/2xbr.c
index b8f45f9c82..b7af9ae027 100644
--- a/gfx/filters/2xbr.c
+++ b/gfx/filters/2xbr.c
@@ -257,6 +257,10 @@ static void twoxbr_generic_output(void *data,
 static void twoxbr_generic_destroy(void *data)
 {
    struct filter_data *filt = (struct filter_data*)data;
+
+   if (!filt)
+      return;
+
    free(filt->workers);
    free(filt);
 }
diff --git a/gfx/filters/2xsai.c b/gfx/filters/2xsai.c
index f2ba760cae..1849b6be98 100644
--- a/gfx/filters/2xsai.c
+++ b/gfx/filters/2xsai.c
@@ -97,6 +97,10 @@ static void twoxsai_generic_output(void *data,
 static void twoxsai_generic_destroy(void *data)
 {
    struct filter_data *filt = (struct filter_data*)data;
+
+   if (!filt)
+      return;
+
    free(filt->workers);
    free(filt);
 }
diff --git a/gfx/filters/blargg_ntsc_snes.c b/gfx/filters/blargg_ntsc_snes.c
index 1cb826ea1e..a37e7b8406 100644
--- a/gfx/filters/blargg_ntsc_snes.c
+++ b/gfx/filters/blargg_ntsc_snes.c
@@ -154,6 +154,9 @@ static void blargg_ntsc_snes_generic_destroy(void *data)
 {
    struct filter_data *filt = (struct filter_data*)data;
 
+   if (!filt)
+      return;
+
    if(filt->ntsc)
       free(filt->ntsc);
 
diff --git a/gfx/filters/darken.c b/gfx/filters/darken.c
index 7421060005..a9d3e29b8a 100644
--- a/gfx/filters/darken.c
+++ b/gfx/filters/darken.c
@@ -95,6 +95,10 @@ static void darken_output(void *data, unsigned *out_width, unsigned *out_height,
 static void darken_destroy(void *data)
 {
    struct filter_data *filt = (struct filter_data*)data;
+
+   if (!filt)
+      return;
+
    free(filt->workers);
    free(filt);
 }
diff --git a/gfx/filters/epx.c b/gfx/filters/epx.c
index c96f348994..3bc5074e3c 100644
--- a/gfx/filters/epx.c
+++ b/gfx/filters/epx.c
@@ -96,6 +96,10 @@ static void epx_generic_output(void *data,
 static void epx_generic_destroy(void *data)
 {
    struct filter_data *filt = (struct filter_data*)data;
+
+   if (!filt)
+      return;
+
    free(filt->workers);
    free(filt);
 }
diff --git a/gfx/filters/lq2x.c b/gfx/filters/lq2x.c
index cb595e1b2a..9c4027cc39 100644
--- a/gfx/filters/lq2x.c
+++ b/gfx/filters/lq2x.c
@@ -96,6 +96,10 @@ static void lq2x_generic_output(void *data,
 static void lq2x_generic_destroy(void *data)
 {
    struct filter_data *filt = (struct filter_data*)data;
+
+   if (!filt)
+      return;
+
    free(filt->workers);
    free(filt);
 }
diff --git a/gfx/filters/phosphor2x.c b/gfx/filters/phosphor2x.c
index 2edba237a2..eaa1c01b56 100644
--- a/gfx/filters/phosphor2x.c
+++ b/gfx/filters/phosphor2x.c
@@ -302,6 +302,10 @@ static void phosphor2x_generic_output(void *data,
 static void phosphor2x_generic_destroy(void *data)
 {
    struct filter_data *filt = (struct filter_data*)data;
+
+   if (!filt)
+      return;
+
    free(filt->workers);
    free(filt);
 }
diff --git a/gfx/filters/scale2x.c b/gfx/filters/scale2x.c
index 54bc3690e2..6d06593983 100644
--- a/gfx/filters/scale2x.c
+++ b/gfx/filters/scale2x.c
@@ -159,6 +159,10 @@ static void scale2x_generic_output(void *data,
 static void scale2x_generic_destroy(void *data)
 {
    struct filter_data *filt = (struct filter_data*)data;
+
+   if (!filt)
+      return;
+
    free(filt->workers);
    free(filt);
 }
diff --git a/gfx/filters/super2xsai.c b/gfx/filters/super2xsai.c
index 9302d21411..ae911bfc24 100644
--- a/gfx/filters/super2xsai.c
+++ b/gfx/filters/super2xsai.c
@@ -96,6 +96,10 @@ static void supertwoxsai_generic_output(void *data, unsigned *out_width, unsigne
 static void supertwoxsai_generic_destroy(void *data)
 {
    struct filter_data *filt = (struct filter_data*)data;
+
+   if (!filt)
+      return;
+
    free(filt->workers);
    free(filt);
 }
diff --git a/gfx/filters/supereagle.c b/gfx/filters/supereagle.c
index 0b8652058e..30a62b1f40 100644
--- a/gfx/filters/supereagle.c
+++ b/gfx/filters/supereagle.c
@@ -96,6 +96,10 @@ static void supereagle_generic_output(void *data, unsigned *out_width, unsigned
 static void supereagle_generic_destroy(void *data)
 {
    struct filter_data *filt = (struct filter_data*)data;
+
+   if (!filt)
+      return;
+
    free(filt->workers);
    free(filt);
 }
diff --git a/gfx/image/image_rpng.c b/gfx/image/image_rpng.c
index 3e5cd02035..d2c43601f0 100644
--- a/gfx/image/image_rpng.c
+++ b/gfx/image/image_rpng.c
@@ -212,6 +212,9 @@ static bool rpng_gx_convert_texture32(struct texture_image *image)
 
 void texture_image_free(struct texture_image *img)
 {
+   if (!img)
+      return;
+
    free(img->pixels);
    memset(img, 0, sizeof(*img));
 }
diff --git a/gfx/rpng/rpng.c b/gfx/rpng/rpng.c
index cd1f87b354..fced321455 100644
--- a/gfx/rpng/rpng.c
+++ b/gfx/rpng/rpng.c
@@ -145,6 +145,9 @@ static bool png_read_chunk(FILE *file, struct png_chunk *chunk)
 
 static void png_free_chunk(struct png_chunk *chunk)
 {
+   if (!chunk)
+      return;
+
    free(chunk->data);
    chunk->data = NULL;
 }
diff --git a/gfx/vg.c b/gfx/vg.c
index 35fa2163fc..039e1c549f 100644
--- a/gfx/vg.c
+++ b/gfx/vg.c
@@ -182,6 +182,9 @@ static void vg_free(void *data)
 {
    vg_t *vg = (vg_t*)data;
 
+   if (!vg)
+      return;
+
    vgDestroyImage(vg->mImage);
 
    if (vg->mFontsOn)
diff --git a/gfx/xvideo.c b/gfx/xvideo.c
index d896f15c51..0f203b7ccd 100644
--- a/gfx/xvideo.c
+++ b/gfx/xvideo.c
@@ -780,6 +780,10 @@ static bool xv_focus(void *data)
 static void xv_free(void *data)
 {
    xv_t *xv = (xv_t*)data;
+
+   if (!xv)
+      return;
+
    x11_destroy_input_context(&xv->xim, &xv->xic);
    XShmDetach(xv->display, &xv->shminfo);
    shmdt(xv->shminfo.shmaddr);
diff --git a/input/gx_input.c b/input/gx_input.c
index c85feb627e..a6aa01cc55 100644
--- a/input/gx_input.c
+++ b/input/gx_input.c
@@ -176,10 +176,13 @@ static void gx_input_free_input(void *data)
 {
    gx_input_t *gx = (gx_input_t*)data;
 
+   if (!gx)
+      return;
+
    if (gx->joypad)
       gx->joypad->destroy();
 
-   free(data);
+   free(gx);
 }
 
 static const char *gx_joypad_name(unsigned pad)
diff --git a/input/overlay.c b/input/overlay.c
index 342f1646e9..90cde1c21a 100644
--- a/input/overlay.c
+++ b/input/overlay.c
@@ -166,6 +166,9 @@ static void input_overlay_free_overlay(struct overlay *overlay)
 {
    size_t i;
 
+   if (!overlay)
+      return;
+
    for (i = 0; i < overlay->size; i++)
       texture_image_free(&overlay->descs[i].image);
 
@@ -177,8 +180,13 @@ static void input_overlay_free_overlay(struct overlay *overlay)
 static void input_overlay_free_overlays(input_overlay_t *ol)
 {
    size_t i;
+
+   if (!ol)
+      return;
+
    for (i = 0; i < ol->size; i++)
       input_overlay_free_overlay(&ol->overlays[i]);
+
    free(ol->overlays);
 }
 
diff --git a/input/psp_input.c b/input/psp_input.c
index fc5bd33880..9aca5a2dba 100644
--- a/input/psp_input.c
+++ b/input/psp_input.c
@@ -127,6 +127,9 @@ static void psp_input_free_input(void *data)
 {
    psp_input_t *psp = (psp_input_t*)data;
 
+   if (!psp)
+      return;
+
    if (psp->joypad)
       psp->joypad->destroy();
 
diff --git a/input/rwebinput_input.c b/input/rwebinput_input.c
index 070db4b5e5..7c2601b83f 100644
--- a/input/rwebinput_input.c
+++ b/input/rwebinput_input.c
@@ -132,9 +132,12 @@ static void rwebinput_input_free(void *data)
    rwebinput_input_t *rwebinput = (rwebinput_input_t*)data;
    uninited = true;
 
+   if (!rwebinput)
+      return;
+
    RWebInputDestroy(rwebinput->context);
 
-   free(data);
+   free(rwebinput);
 }
 
 static void rwebinput_input_poll(void *data)
diff --git a/input/x11_input.c b/input/x11_input.c
index d0033ccf22..aab14a5884 100644
--- a/input/x11_input.c
+++ b/input/x11_input.c
@@ -230,10 +230,13 @@ static void x_input_free(void *data)
 {
    x11_input_t *x11 = (x11_input_t*)data;
 
+   if (!x11)
+      return;
+
    if (x11->joypad)
       x11->joypad->destroy();
 
-   free(data);
+   free(x11);
 }
 
 static void x_input_poll_mouse(x11_input_t *x11)
diff --git a/input/xdk_xinput_input.c b/input/xdk_xinput_input.c
index 14289ac8df..383e252de2 100644
--- a/input/xdk_xinput_input.c
+++ b/input/xdk_xinput_input.c
@@ -183,10 +183,13 @@ static void xdk_input_free_input(void *data)
 {
    xdk_input_t *xdk = (xdk_input_t*)data;
 
+   if (!xdk)
+      return;
+
    if (xdk->joypad)
       xdk->joypad->destroy();
 
-   free(data);
+   free(xdk);
 }
 
 static void *xdk_input_init(void)
diff --git a/rewind.c b/rewind.c
index 04c6878663..2d1e846ed3 100644
--- a/rewind.c
+++ b/rewind.c
@@ -170,6 +170,9 @@ error:
 
 void state_manager_free(state_manager_t *state)
 {
+   if (!state)
+      return;
+
    free(state->data);
    free(state->thisblock);
    free(state->nextblock);
diff --git a/thread.c b/thread.c
index 200df36452..3791f5d92f 100644
--- a/thread.c
+++ b/thread.c
@@ -122,6 +122,9 @@ slock_t *slock_new(void)
 
 void slock_free(slock_t *lock)
 {
+   if (!lock)
+      return;
+
    CloseHandle(lock->lock);
    free(lock);
 }
@@ -201,6 +204,9 @@ int scond_broadcast(scond_t *cond)
 
 void scond_free(scond_t *cond)
 {
+   if (!cond)
+      return;
+
    CloseHandle(cond->event);
    free(cond);
 }
@@ -279,6 +285,9 @@ slock_t *slock_new(void)
 
 void slock_free(slock_t *lock)
 {
+   if (!lock)
+      return;
+
    pthread_mutex_destroy(&lock->lock);
    free(lock);
 }
@@ -315,6 +324,9 @@ scond_t *scond_new(void)
 
 void scond_free(scond_t *cond)
 {
+   if (!cond)
+      return;
+
    pthread_cond_destroy(&cond->cond);
    free(cond);
 }