Skip to content

Commit

Permalink
Fixed bug 1821 - IMG_LoadLBM/PNM/XCF_RW() crash with a heap corruptio…
Browse files Browse the repository at this point in the history
…n on loading LBM, PNM or XCF images

Marcus von Appen

Trying to load a LBM image via any of the IMG_* functions will lead to a heap corruption on Windows 7, causing the application to crash.

The problem is caused by the usage of SDL_malloc on Win32, which by default uses dlmalloc, which in turn redefines malloc and free within the SDL address space.

The CRT heap manager hence is unaware of the pointer being allocated and will try to free an unmanaged memory segment by calling free() on the temporary buffer in IMG_LoadLBM_RW().
  • Loading branch information
slouken committed Apr 25, 2013
1 parent 3ce14c9 commit adc59da
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 22 deletions.
2 changes: 1 addition & 1 deletion IMG_lbm.c
Expand Up @@ -467,7 +467,7 @@ SDL_Surface *IMG_LoadLBM_RW( SDL_RWops *src )

done:

if ( MiniBuf ) free( MiniBuf );
if ( MiniBuf ) SDL_free( MiniBuf );

if ( error )
{
Expand Down
4 changes: 2 additions & 2 deletions IMG_pcx.c
Expand Up @@ -149,7 +149,7 @@ SDL_Surface *IMG_LoadPCX_RW(SDL_RWops *src)
if (bpl > surface->pitch) {
error = "bytes per line is too large (corrupt?)";
}
buf = (Uint8 *)malloc(bpl);
buf = (Uint8 *)SDL_malloc(bpl);
row = (Uint8 *)surface->pixels;
for ( y=0; y<surface->h; ++y ) {
/* decode a scan line to a temporary buffer first */
Expand Down Expand Up @@ -247,7 +247,7 @@ SDL_Surface *IMG_LoadPCX_RW(SDL_RWops *src)
}

done:
free(buf);
SDL_free(buf);
if ( error ) {
SDL_RWseek(src, start, RW_SEEK_SET);
if ( surface ) {
Expand Down
2 changes: 1 addition & 1 deletion IMG_pnm.c
Expand Up @@ -229,7 +229,7 @@ SDL_Surface *IMG_LoadPNM_RW(SDL_RWops *src)
row += surface->pitch;
}
done:
free(buf);
SDL_free(buf);
if(error) {
SDL_RWseek(src, start, RW_SEEK_SET);
if ( surface ) {
Expand Down
36 changes: 18 additions & 18 deletions IMG_xcf.c
Expand Up @@ -231,7 +231,7 @@ static char * read_string (SDL_RWops * src) {

tmp = SDL_ReadBE32 (src);
if (tmp > 0) {
data = (char *) malloc (sizeof (char) * tmp);
data = (char *) SDL_malloc (sizeof (char) * tmp);
SDL_RWread (src, data, tmp, 1);
}
else {
Expand Down Expand Up @@ -261,7 +261,7 @@ static void xcf_read_property (SDL_RWops * src, xcf_prop * prop) {
switch (prop->id) {
case PROP_COLORMAP:
prop->data.colormap.num = SDL_ReadBE32 (src);
prop->data.colormap.cmap = (char *) malloc (sizeof (char) * prop->data.colormap.num * 3);
prop->data.colormap.cmap = (char *) SDL_malloc (sizeof (char) * prop->data.colormap.num * 3);
SDL_RWread (src, prop->data.colormap.cmap, prop->data.colormap.num*3, 1);
break;

Expand All @@ -287,16 +287,16 @@ static void xcf_read_property (SDL_RWops * src, xcf_prop * prop) {

static void free_xcf_header (xcf_header * h) {
if (h->cm_num)
free (h->cm_map);
SDL_free (h->cm_map);

free (h);
SDL_free (h);
}

static xcf_header * read_xcf_header (SDL_RWops * src) {
xcf_header * h;
xcf_prop prop;

h = (xcf_header *) malloc (sizeof (xcf_header));
h = (xcf_header *) SDL_malloc (sizeof (xcf_header));
SDL_RWread (src, h->sign, 14, 1);
h->width = SDL_ReadBE32 (src);
h->height = SDL_ReadBE32 (src);
Expand All @@ -318,23 +318,23 @@ static xcf_header * read_xcf_header (SDL_RWops * src) {
h->cm_num = prop.data.colormap.num;
h->cm_map = (unsigned char *) SDL_malloc (sizeof (unsigned char) * 3 * h->cm_num);
memcpy (h->cm_map, prop.data.colormap.cmap, 3*sizeof (char)*h->cm_num);
free (prop.data.colormap.cmap);
SDL_free (prop.data.colormap.cmap);
}
} while (prop.id != PROP_END);

return h;
}

static void free_xcf_layer (xcf_layer * l) {
free (l->name);
free (l);
SDL_free (l->name);
SDL_free (l);
}

static xcf_layer * read_xcf_layer (SDL_RWops * src) {
xcf_layer * l;
xcf_prop prop;

l = (xcf_layer *) malloc (sizeof (xcf_layer));
l = (xcf_layer *) SDL_malloc (sizeof (xcf_layer));
l->width = SDL_ReadBE32 (src);
l->height = SDL_ReadBE32 (src);
l->layer_type = SDL_ReadBE32 (src);
Expand All @@ -358,8 +358,8 @@ static xcf_layer * read_xcf_layer (SDL_RWops * src) {
}

static void free_xcf_channel (xcf_channel * c) {
free (c->name);
free (c);
SDL_free (c->name);
SDL_free (c);
}

static xcf_channel * read_xcf_channel (SDL_RWops * src) {
Expand Down Expand Up @@ -401,15 +401,15 @@ static xcf_channel * read_xcf_channel (SDL_RWops * src) {
}

static void free_xcf_hierarchy (xcf_hierarchy * h) {
free (h->level_file_offsets);
free (h);
SDL_free (h->level_file_offsets);
SDL_free (h);
}

static xcf_hierarchy * read_xcf_hierarchy (SDL_RWops * src) {
xcf_hierarchy * h;
int i;

h = (xcf_hierarchy *) malloc (sizeof (xcf_hierarchy));
h = (xcf_hierarchy *) SDL_malloc (sizeof (xcf_hierarchy));
h->width = SDL_ReadBE32 (src);
h->height = SDL_ReadBE32 (src);
h->bpp = SDL_ReadBE32 (src);
Expand All @@ -425,8 +425,8 @@ static xcf_hierarchy * read_xcf_hierarchy (SDL_RWops * src) {
}

static void free_xcf_level (xcf_level * l) {
free (l->tile_file_offsets);
free (l);
SDL_free (l->tile_file_offsets);
SDL_free (l);
}

static xcf_level * read_xcf_level (SDL_RWops * src) {
Expand All @@ -448,7 +448,7 @@ static xcf_level * read_xcf_level (SDL_RWops * src) {
}

static void free_xcf_tile (unsigned char * t) {
free (t);
SDL_free (t);
}

static unsigned char * load_xcf_tile_none (SDL_RWops * src, Uint32 len, int bpp, int x, int y) {
Expand All @@ -469,7 +469,7 @@ static unsigned char * load_xcf_tile_rle (SDL_RWops * src, Uint32 len, int bpp,
t = load = (unsigned char *) SDL_malloc (len);
reallen = SDL_RWread (src, t, 1, len);

data = (unsigned char *) malloc (x*y*bpp);
data = (unsigned char *) SDL_malloc (x*y*bpp);
for (i = 0; i < bpp; i++) {
d = data + i;
size = x*y;
Expand Down

0 comments on commit adc59da

Please sign in to comment.