@@ -280,6 +280,17 @@ char const * caca_get_version(void) | |||||
return PACKAGE_VERSION; | 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. | * XXX: The following functions are local. | ||||
*/ | */ | ||||
@@ -259,6 +259,9 @@ extern int _pop_event(caca_display_t *, caca_privevent_t *); | |||||
/* Internal window functions */ | /* Internal window functions */ | ||||
extern void _caca_set_term_title(char const *); | 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 */ | /* Profiling functions */ | ||||
#if defined PROF | #if defined PROF | ||||
extern void _caca_dump_stats(void); | extern void _caca_dump_stats(void); | ||||
@@ -204,15 +204,15 @@ static BOOL s_quitting = NO; | |||||
if(_attrs) | if(_attrs) | ||||
free(_attrs); | free(_attrs); | ||||
_attrs = malloc(_w * _h * sizeof(uint32_t) * 2); | |||||
_attrs = _caca_alloc2d(_w , _h, sizeof(uint32_t) * 2); | |||||
if(_bkg_rects) | if(_bkg_rects) | ||||
free(_bkg_rects); | free(_bkg_rects); | ||||
_bkg_rects = malloc(_w * _h * sizeof(NSRect)); | |||||
_bkg_rects = _caca_alloc2d(_w, _h, sizeof(NSRect)); | |||||
if(_bkg_colors) | if(_bkg_colors) | ||||
free(_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, | // [[self window] setContentSize: NSMakeSize(caca_get_canvas_width(dp->cv) * _font_rect.size.width, | ||||
// caca_get_canvas_height(dp->cv) * _font_rect.size.height)]; | // caca_get_canvas_height(dp->cv) * _font_rect.size.height)]; | ||||
@@ -166,8 +166,7 @@ static int win32_init_graphics(caca_display_t *dp) | |||||
SetConsoleActiveScreenBuffer(dp->drv.p->screen); | 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) | if(dp->drv.p->buffer == NULL) | ||||
return -1; | return -1; | ||||
@@ -425,7 +425,7 @@ int caca_render_canvas(caca_canvas_t const *cv, caca_font_t const *f, | |||||
} | } | ||||
if(f->header.bpp != 8) | 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) | if(width < cv->width * f->header.width) | ||||
xmax = width / f->header.width; | xmax = width / f->header.width; | ||||
@@ -269,14 +269,14 @@ int caca_rotate_left(caca_canvas_t *cv) | |||||
w2 = (cv->width + 1) / 2; | w2 = (cv->width + 1) / 2; | ||||
h2 = cv->height; | h2 = cv->height; | ||||
newchars = malloc(w2 * h2 * 2 * sizeof(uint32_t)); | |||||
newchars = _caca_alloc2d(w2, h2, 2 * sizeof(uint32_t)); | |||||
if(!newchars) | if(!newchars) | ||||
{ | { | ||||
seterrno(ENOMEM); | seterrno(ENOMEM); | ||||
return -1; | return -1; | ||||
} | } | ||||
newattrs = malloc(w2 * h2 * 2 * sizeof(uint32_t)); | |||||
newattrs = _caca_alloc2d(w2, h2, 2 * sizeof(uint32_t)); | |||||
if(!newattrs) | if(!newattrs) | ||||
{ | { | ||||
free(newchars); | free(newchars); | ||||
@@ -389,14 +389,14 @@ int caca_rotate_right(caca_canvas_t *cv) | |||||
w2 = (cv->width + 1) / 2; | w2 = (cv->width + 1) / 2; | ||||
h2 = cv->height; | h2 = cv->height; | ||||
newchars = malloc(w2 * h2 * 2 * sizeof(uint32_t)); | |||||
newchars = _caca_alloc2d(w2 * 2, h2, sizeof(uint32_t)); | |||||
if(!newchars) | if(!newchars) | ||||
{ | { | ||||
seterrno(ENOMEM); | seterrno(ENOMEM); | ||||
return -1; | return -1; | ||||
} | } | ||||
newattrs = malloc(w2 * h2 * 2 * sizeof(uint32_t)); | |||||
newattrs = _caca_alloc2d(w2 * 2, h2, sizeof(uint32_t)); | |||||
if(!newattrs) | if(!newattrs) | ||||
{ | { | ||||
free(newchars); | free(newchars); | ||||
@@ -504,14 +504,14 @@ int caca_stretch_left(caca_canvas_t *cv) | |||||
/* Save the current frame shortcuts */ | /* Save the current frame shortcuts */ | ||||
_caca_save_frame_info(cv); | _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) | if(!newchars) | ||||
{ | { | ||||
seterrno(ENOMEM); | seterrno(ENOMEM); | ||||
return -1; | return -1; | ||||
} | } | ||||
newattrs = malloc(cv->width * cv->height * sizeof(uint32_t)); | |||||
newattrs = _caca_alloc2d(cv->width, cv->height, sizeof(uint32_t)); | |||||
if(!newattrs) | if(!newattrs) | ||||
{ | { | ||||
free(newchars); | free(newchars); | ||||
@@ -597,14 +597,14 @@ int caca_stretch_right(caca_canvas_t *cv) | |||||
/* Save the current frame shortcuts */ | /* Save the current frame shortcuts */ | ||||
_caca_save_frame_info(cv); | _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) | if(!newchars) | ||||
{ | { | ||||
seterrno(ENOMEM); | seterrno(ENOMEM); | ||||
return -1; | return -1; | ||||
} | } | ||||
newattrs = malloc(cv->width * cv->height * sizeof(uint32_t)); | |||||
newattrs = _caca_alloc2d(cv->width, cv->height, sizeof(uint32_t)); | |||||
if(!newattrs) | if(!newattrs) | ||||
{ | { | ||||
free(newchars); | free(newchars); | ||||
@@ -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"); | 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) | if(buf == NULL) | ||||
{ | { | ||||
rb_raise(rb_eNoMemError, "Out of memory"); | rb_raise(rb_eNoMemError, "Out of memory"); | ||||
@@ -103,6 +103,14 @@ struct image * load_image(char const * name) | |||||
uint32_t bpp = u16fread(f); | uint32_t bpp = u16fread(f); | ||||
uint32_t colors = 0; | uint32_t colors = 0; | ||||
/* Sanity check */ | |||||
if (planes != 1) | |||||
{ | |||||
caca_file_close(f); | |||||
free(im); | |||||
return NULL; | |||||
} | |||||
if (header_size == 40) | if (header_size == 40) | ||||
{ | { | ||||
if (u32fread(f) != 0) /* compression */ | if (u32fread(f) != 0) /* compression */ | ||||
@@ -152,16 +160,8 @@ struct image * load_image(char const * name) | |||||
uint32_t depth = (bpp + 7) / 8; | 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 */ | /* Allocate the pixel buffer */ | ||||
im->pixels = malloc(im->w * im->h * depth); | |||||
im->pixels = _caca_alloc2d(im->w, im->h, depth); | |||||
if (!im->pixels) | if (!im->pixels) | ||||
{ | { | ||||
caca_file_close(f); | caca_file_close(f); | ||||