diff --git a/caca/caca.c b/caca/caca.c
index ae667ec..ddcb92e 100644
--- a/caca/caca.c
+++ b/caca/caca.c
@@ -280,6 +280,17 @@ char const * caca_get_version(void)
     return PACKAGE_VERSION;
 }
 
+/*
+ * XXX: The following functions are private.
+ */
+
+extern void *_caca_alloc2d(size_t width, size_t height, size_t elem_size)
+{
+    if (width == 0 || height == 0 || elem_size == 0 || SIZE_MAX / width / height < elem_size)
+        return NULL;
+    return malloc(width * height * elem_size);
+}
+
 /*
  * XXX: The following functions are local.
  */
diff --git a/caca/caca_internals.h b/caca/caca_internals.h
index 84d790b..40b455c 100644
--- a/caca/caca_internals.h
+++ b/caca/caca_internals.h
@@ -259,6 +259,9 @@ extern int _pop_event(caca_display_t *, caca_privevent_t *);
 /* Internal window functions */
 extern void _caca_set_term_title(char const *);
 
+/* Internal memory function */
+extern void *_caca_alloc2d(size_t width, size_t height, size_t elem_size);
+
 /* Profiling functions */
 #if defined PROF
 extern void _caca_dump_stats(void);
diff --git a/caca/driver/cocoa.m b/caca/driver/cocoa.m
index 86c8a63..a72b86b 100644
--- a/caca/driver/cocoa.m
+++ b/caca/driver/cocoa.m
@@ -204,15 +204,15 @@ static BOOL s_quitting = NO;
 
         if(_attrs)
             free(_attrs);
-        _attrs = malloc(_w * _h * sizeof(uint32_t) * 2);
+        _attrs = _caca_alloc2d(_w , _h, sizeof(uint32_t) * 2);
 
         if(_bkg_rects)
             free(_bkg_rects);
-        _bkg_rects = malloc(_w * _h * sizeof(NSRect));
+        _bkg_rects = _caca_alloc2d(_w, _h, sizeof(NSRect));
 
         if(_bkg_colors)
             free(_bkg_colors);
-        _bkg_colors = malloc(_w * _h * sizeof(NSColor*));
+        _bkg_colors = _caca_alloc2d(_w, _h, sizeof(NSColor*));
 
       //  [[self window] setContentSize: NSMakeSize(caca_get_canvas_width(dp->cv) * _font_rect.size.width,
      //                                             caca_get_canvas_height(dp->cv) * _font_rect.size.height)];
diff --git a/caca/driver/win32.c b/caca/driver/win32.c
index 7e26707..2439a97 100644
--- a/caca/driver/win32.c
+++ b/caca/driver/win32.c
@@ -166,8 +166,7 @@ static int win32_init_graphics(caca_display_t *dp)
 
     SetConsoleActiveScreenBuffer(dp->drv.p->screen);
 
-    dp->drv.p->buffer = malloc(width * height
-                               * sizeof(CHAR_INFO));
+    dp->drv.p->buffer = _caca_alloc2d(width, height, sizeof(CHAR_INFO));
     if(dp->drv.p->buffer == NULL)
         return -1;
 
diff --git a/caca/font.c b/caca/font.c
index c898ea0..a7ce7bc 100644
--- a/caca/font.c
+++ b/caca/font.c
@@ -425,7 +425,7 @@ int caca_render_canvas(caca_canvas_t const *cv, caca_font_t const *f,
     }
 
     if(f->header.bpp != 8)
-        glyph = malloc(f->header.width * 2 * f->header.height);
+        glyph = _caca_alloc2d(f->header.width, f->header.height, 2);
 
     if(width < cv->width * f->header.width)
         xmax = width / f->header.width;
diff --git a/caca/transform.c b/caca/transform.c
index 408ae19..a8c7457 100644
--- a/caca/transform.c
+++ b/caca/transform.c
@@ -269,14 +269,14 @@ int caca_rotate_left(caca_canvas_t *cv)
     w2 = (cv->width + 1) / 2;
     h2 = cv->height;
 
-    newchars = malloc(w2 * h2 * 2 * sizeof(uint32_t));
+    newchars = _caca_alloc2d(w2, h2, 2 * sizeof(uint32_t));
     if(!newchars)
     {
         seterrno(ENOMEM);
         return -1;
     }
 
-    newattrs = malloc(w2 * h2 * 2 * sizeof(uint32_t));
+    newattrs = _caca_alloc2d(w2, h2, 2 * sizeof(uint32_t));
     if(!newattrs)
     {
         free(newchars);
@@ -389,14 +389,14 @@ int caca_rotate_right(caca_canvas_t *cv)
     w2 = (cv->width + 1) / 2;
     h2 = cv->height;
 
-    newchars = malloc(w2 * h2 * 2 * sizeof(uint32_t));
+    newchars = _caca_alloc2d(w2 * 2, h2, sizeof(uint32_t));
     if(!newchars)
     {
         seterrno(ENOMEM);
         return -1;
     }
 
-    newattrs = malloc(w2 * h2 * 2 * sizeof(uint32_t));
+    newattrs = _caca_alloc2d(w2 * 2, h2, sizeof(uint32_t));
     if(!newattrs)
     {
         free(newchars);
@@ -504,14 +504,14 @@ int caca_stretch_left(caca_canvas_t *cv)
     /* Save the current frame shortcuts */
     _caca_save_frame_info(cv);
 
-    newchars = malloc(cv->width * cv->height * sizeof(uint32_t));
+    newchars = _caca_alloc2d(cv->width, cv->height, sizeof(uint32_t));
     if(!newchars)
     {
         seterrno(ENOMEM);
         return -1;
     }
 
-    newattrs = malloc(cv->width * cv->height * sizeof(uint32_t));
+    newattrs = _caca_alloc2d(cv->width, cv->height, sizeof(uint32_t));
     if(!newattrs)
     {
         free(newchars);
@@ -597,14 +597,14 @@ int caca_stretch_right(caca_canvas_t *cv)
     /* Save the current frame shortcuts */
     _caca_save_frame_info(cv);
 
-    newchars = malloc(cv->width * cv->height * sizeof(uint32_t));
+    newchars = _caca_alloc2d(cv->width, cv->height, sizeof(uint32_t));
     if(!newchars)
     {
         seterrno(ENOMEM);
         return -1;
     }
 
-    newattrs = malloc(cv->width * cv->height * sizeof(uint32_t));
+    newattrs = _caca_alloc2d(cv->width, cv->height, sizeof(uint32_t));
     if(!newattrs)
     {
         free(newchars);
diff --git a/ruby/caca-canvas.c b/ruby/caca-canvas.c
index 43a3ad4..a55fe60 100644
--- a/ruby/caca-canvas.c
+++ b/ruby/caca-canvas.c
@@ -583,7 +583,7 @@ static VALUE render_canvas(VALUE self, VALUE font, VALUE width, VALUE height, VA
         rb_raise(rb_eArgError, "First argument is not a Caca::Font");
     }
 
-    buf = malloc(width*height*4);
+    buf = _caca_alloc2d(width, height, 4);
     if(buf == NULL)
     {
         rb_raise(rb_eNoMemError, "Out of memory");
diff --git a/src/common-image.c b/src/common-image.c
index 43e756c..584b846 100644
--- a/src/common-image.c
+++ b/src/common-image.c
@@ -103,6 +103,14 @@ struct image * load_image(char const * name)
     uint32_t bpp = u16fread(f);
     uint32_t colors = 0;
 
+    /* Sanity check */
+    if (planes != 1)
+    {
+        caca_file_close(f);
+        free(im);
+        return NULL;
+    }
+
     if (header_size == 40)
     {
         if (u32fread(f) != 0) /* compression */
@@ -152,16 +160,8 @@ struct image * load_image(char const * name)
 
     uint32_t depth = (bpp + 7) / 8;
 
-    /* Sanity check */
-    if (!depth || !im->w || im->w > 0x10000 || !im->h || im->h > 0x10000 || planes != 1)
-    {
-        caca_file_close(f);
-        free(im);
-        return NULL;
-    }
-
     /* Allocate the pixel buffer */
-    im->pixels = malloc(im->w * im->h * depth);
+    im->pixels = _caca_alloc2d(im->w, im->h, depth);
     if (!im->pixels)
     {
         caca_file_close(f);