Skip to content

Commit

Permalink
backports of multiple bug fixes from 2.0:
Browse files Browse the repository at this point in the history
3999783e (r340): bug 1413 - Fix image corruption when using ImageIO framework
5bf0f0d6 (r343), 326a6025 (r361): fixes from VS code analysis and code review
2742fe58 (r355), 1e7a55d7 (r356). dd40be56 (r358): support for webp on big endian systems
ce8091ca (r365): bug 1801 - typo in the xcf decoder, condition is always false
35beff02 (r369): bug 1831 - Memory leak issue in SDL_image-1.2.12/IMG_xpm.c file
1700d607 (r415): bug 1991 - XCF and LBM image loading [only the memory leak parts.]
e108e122 (r419): bug 2010 - Memory leaks in do_layer_surface function in IMG_xcf.c
7a360f7d (r436): bug 2295 - Memory leak in IMG_LoadWEBP_RW
ee17b8eb (r443): bug 2454 - Crash when loading some XPM files
bca82f1c (r476): proper fix for Bugzilla #2965.
fd721465 (r490): crash if some initialization succeeded and some didn't
915de300 (r492): bug 3474 - IMG_tif leaks memory on errors
b6f8fbe5 (r493): bug 3475 - Remove unnecessary loop from IMG_tif.c
d3e819a0 (r499): bug 2318 - h->cm_map resource getting leak in read_xcf_header function
1e32e1f4 (r503): bug 3008 - Compiler warnings: "warning: initialization discards 'const'
318484db (r513): security vulnerability in XCF image loader
181ef57f (r530): failing to reset the file pointer when detecting file types with ImageIO
16772bbb (r555): lbm: use correct variable to check color planes.
97f7f01e (r556): lbm: Fail to load images with unsupported/bogus color depth.
bfa08dc0 (r557): lbm: Don't overflow static colormap buffer.
a1e9b624 (r558): ico: reject obviously incorrect image sizes.
37445f61 (r559): bmp: don't overflow palette buffer with bogus biClrUsed values.
7df1580f (r560): xcf: deal with bogus data in rle tile decoding.
45e750f9 (r563): gif: report error on bogus LWZ data, instead of overflowing a buffer.
2938fc80 (r567): pcx: don't overflow buffer if bytes-per-line is less than image width.
c5f9cbb5 (r568): xcf: Prevent infinite loop and/or buffer overflow on bogus data.
fb643e37 (r569): xcf: check for some potential integer overflows.
170d7d32 (r585): potential buffer overflow on corrupt or maliciously-crafted XCF file.
19beb4a1 (r586): Don't get into infinite loops on truncated GIF files.
32a18ca0 (r587): Don't get into infinite loops on truncated PNM files.
8b4ee1d7 (r590): memory leak in IMG_xcf.c
90a531f2 (r591): PNM: Improve checks when loading a file
31263a04 (r592): XCF: check if there's sufficient data in the stream before allocating
cec9b759 (r593): More error checking, and null terminate strings...
  • Loading branch information
sezero committed Oct 16, 2018
1 parent cabcf89 commit 1c1755e
Show file tree
Hide file tree
Showing 14 changed files with 286 additions and 119 deletions.
2 changes: 1 addition & 1 deletion IMG.c
Expand Up @@ -31,7 +31,7 @@

/* Table of image detection and loading functions */
static struct {
char *type;
const char *type;
int (SDLCALL *is)(SDL_RWops *src);
SDL_Surface *(SDLCALL *load)(SDL_RWops *src);
} supported[] = {
Expand Down
18 changes: 12 additions & 6 deletions IMG_ImageIO.m
Expand Up @@ -217,13 +217,13 @@ static CFDictionaryRef CreateHintDictionary(CFStringRef uti_string_hint)
* libpng loader.
* Thanks to Allegro. :)
*/
CGFloat whitePoint[3] = { 1, 1, 1 };
CGFloat blackPoint[3] = { 0, 0, 0 };
CGFloat whitePoint[3] = { 0.950, 1.000, 1.089 };
CGFloat blackPoint[3] = { 0.000, 0.000, 0.000 };
CGFloat gamma[3] = { 2.2, 2.2, 2.2 };
CGFloat matrix[9] = {
1, 1, 1,
1, 1, 1,
1, 1, 1
0.412, 0.213, 0.019,
0.358, 0.715, 0.119,
0.180, 0.072, 0.950
};
CGColorSpaceRef color_space =
CGColorSpaceCreateCalibratedRGB(
Expand Down Expand Up @@ -521,7 +521,7 @@ static int Internal_isType_UIImage (SDL_RWops *rw_ops, CFStringRef uti_string_to
}
}

// reset the file descption pointer
// reset the file pointer
SDL_RWseek(rw_ops, start, SEEK_SET);

#endif /* #if defined(ALLOW_UIIMAGE_FALLBACK) && ((TARGET_OS_IPHONE == 1) || (TARGET_IPHONE_SIMULATOR == 1)) */
Expand All @@ -532,6 +532,7 @@ static int Internal_isType_ImageIO (SDL_RWops *rw_ops, CFStringRef uti_string_to
{
int is_type = 0;

Sint32 start = SDL_RWtell(rw_ops);
CFDictionaryRef hint_dictionary = CreateHintDictionary(uti_string_to_test);
CGImageSourceRef image_source = CreateCGImageSourceFromRWops(rw_ops, hint_dictionary);

Expand All @@ -540,6 +541,8 @@ static int Internal_isType_ImageIO (SDL_RWops *rw_ops, CFStringRef uti_string_to
}

if (NULL == image_source) {
// reset the file pointer
SDL_RWseek(rw_ops, start, SEEK_SET);
return 0;
}

Expand All @@ -555,6 +558,9 @@ static int Internal_isType_ImageIO (SDL_RWops *rw_ops, CFStringRef uti_string_to
is_type = (int)UTTypeConformsTo(uti_string_to_test, uti_type);

CFRelease(image_source);

// reset the file pointer
SDL_RWseek(rw_ops, start, SEEK_SET);
return is_type;
}

Expand Down
21 changes: 21 additions & 0 deletions IMG_bmp.c
Expand Up @@ -662,6 +662,22 @@ LoadICOCUR_RW(SDL_RWops * src, int type, int freesrc)
goto done;
}

/* sanity check image size, so we don't overflow integers, etc. */
if ((biWidth < 0) || (biWidth > 0xFFFFFF) ||
(biHeight < 0) || (biHeight > 0xFFFFFF)) {
IMG_SetError("Unsupported or invalid ICO dimensions");
was_error = SDL_TRUE;
goto done;
}

/* sanity check image size, so we don't overflow integers, etc. */
if ((biWidth < 0) || (biWidth > 0xFFFFFF) ||
(biHeight < 0) || (biHeight > 0xFFFFFF)) {
IMG_SetError("Unsupported or invalid ICO dimensions");
was_error = SDL_TRUE;
goto done;
}

/* Create a RGBA surface */
biHeight = biHeight >> 1;
//printf("%d x %d\n", biWidth, biHeight);
Expand All @@ -679,6 +695,11 @@ LoadICOCUR_RW(SDL_RWops * src, int type, int freesrc)
if (biClrUsed == 0) {
biClrUsed = 1 << biBitCount;
}
if (biClrUsed > (sizeof(palette)/sizeof(palette[0]))) {
IMG_SetError("Unsupported or incorrect biClrUsed field");
was_error = SDL_TRUE;
goto done;
}
for (i = 0; i < (int) biClrUsed; ++i) {
SDL_RWread(src, &palette[i], 4, 1);
}
Expand Down
25 changes: 19 additions & 6 deletions IMG_gif.c
Expand Up @@ -320,7 +320,7 @@ DoExtension(SDL_RWops *src, int label)
break;
case 0xfe: /* Comment Extension */
str = "Comment Extension";
while (GetDataBlock(src, (unsigned char *) buf) != 0)
while (GetDataBlock(src, (unsigned char *) buf) > 0)
;
return FALSE;
case 0xf9: /* Graphic Control Extension */
Expand All @@ -332,7 +332,7 @@ DoExtension(SDL_RWops *src, int label)
if ((buf[0] & 0x1) != 0)
Gif89.transparent = buf[3];

while (GetDataBlock(src, (unsigned char *) buf) != 0)
while (GetDataBlock(src, (unsigned char *) buf) > 0)
;
return FALSE;
default:
Expand All @@ -341,7 +341,7 @@ DoExtension(SDL_RWops *src, int label)
break;
}

while (GetDataBlock(src, (unsigned char *) buf) != 0)
while (GetDataBlock(src, (unsigned char *) buf) > 0)
;

return FALSE;
Expand Down Expand Up @@ -390,7 +390,7 @@ GetCode(SDL_RWops *src, int code_size, int flag)
buf[0] = buf[last_byte - 2];
buf[1] = buf[last_byte - 1];

if ((count = GetDataBlock(src, &buf[2])) == 0)
if ((count = GetDataBlock(src, &buf[2])) <= 0)
done = TRUE;

last_byte = 2 + count;
Expand Down Expand Up @@ -439,8 +439,9 @@ LWZReadByte(SDL_RWops *src, int flag, int input_code_size)
table[0][i] = 0;
table[1][i] = i;
}
table[1][0] = 0;
for (; i < (1 << MAX_LWZ_BITS); ++i)
table[0][i] = table[1][0] = 0;
table[0][i] = 0;

sp = stack;

Expand Down Expand Up @@ -493,12 +494,24 @@ LWZReadByte(SDL_RWops *src, int flag, int input_code_size)
code = oldcode;
}
while (code >= clear_code) {
/* Guard against buffer overruns */
if (code < 0 || code >= (1 << MAX_LWZ_BITS)) {
RWSetMsg("invalid LWZ data");
return -3;
}
*sp++ = table[1][code];
if (code == table[0][code])
if (code == table[0][code]) {
RWSetMsg("circular table entry BIG ERROR");
return -3;
}
code = table[0][code];
}

/* Guard against buffer overruns */
if (code < 0 || code >= (1 << MAX_LWZ_BITS)) {
RWSetMsg("invalid LWZ data");
return -4;
}
*sp++ = firstcode = table[1][code];

if ((code = max_code) < (1 << MAX_LWZ_BITS)) {
Expand Down
10 changes: 5 additions & 5 deletions IMG_jpg.c
Expand Up @@ -214,13 +214,13 @@ int IMG_isJPG(SDL_RWops *src)
is_JPG = 0;
} else {
/* Yes, it's big-endian */
Uint32 start;
Sint32 innerStart;
Uint32 size;
Uint32 end;
start = SDL_RWtell(src);
Sint32 end;
innerStart = SDL_RWtell(src);
size = (magic[2] << 8) + magic[3];
end = SDL_RWseek(src, size-2, RW_SEEK_CUR);
if ( end != start + size - 2 ) is_JPG = 0;
if ( end != innerStart + size - 2 ) is_JPG = 0;
if ( magic[1] == 0xDA ) {
/* Now comes the actual JPEG meat */
#ifdef FAST_IS_JPEG
Expand Down Expand Up @@ -386,7 +386,7 @@ SDL_Surface *IMG_LoadJPG_RW(SDL_RWops *src)
}
start = SDL_RWtell(src);

if ( !IMG_Init(IMG_INIT_JPG) ) {
if ( (IMG_Init(IMG_INIT_JPG) & IMG_INIT_JPG) == 0 ) {
return NULL;
}

Expand Down
25 changes: 18 additions & 7 deletions IMG_lbm.c
Expand Up @@ -187,6 +187,11 @@ SDL_Surface *IMG_LoadLBM_RW( SDL_RWops *src )

if ( !memcmp( id, "CMAP", 4 ) ) /* palette ( Color Map ) */
{
if (size > sizeof (colormap)) {
error="colormap size is too large";
goto done;
}

if ( !SDL_RWread( src, &colormap, size, 1 ) )
{
error="error reading CMAP chunk";
Expand Down Expand Up @@ -237,19 +242,25 @@ SDL_Surface *IMG_LoadLBM_RW( SDL_RWops *src )
nbplanes = 1;
}

if ((nbplanes != 1) && (nbplanes != 4) && (nbplanes != 8) && (nbplanes != 24))
{
error="unsupported number of color planes";
goto done;
}

stencil = (bmhd.mask & 1); /* There is a mask ( 'stencil' ) */

/* Allocate memory for a temporary buffer ( used for
decompression/deinterleaving ) */

MiniBuf = (void *)malloc( bytesperline * (nbplanes + stencil) );
MiniBuf = (Uint8 *)malloc( bytesperline * (nbplanes + stencil) );
if ( MiniBuf == NULL )
{
error="no enough memory for temporary buffer";
error="not enough memory for temporary buffer";
goto done;
}

if ( ( Image = SDL_CreateRGBSurface( SDL_SWSURFACE, width, bmhd.h, (bmhd.planes==24 || flagHAM==1)?24:8, 0, 0, 0, 0 ) ) == NULL )
if ( ( Image = SDL_CreateRGBSurface( SDL_SWSURFACE, width, bmhd.h, (nbplanes==24 || flagHAM==1)?24:8, 0, 0, 0, 0 ) ) == NULL )
goto done;

if ( bmhd.mask & 2 ) /* There is a transparent color */
Expand All @@ -276,7 +287,7 @@ SDL_Surface *IMG_LoadLBM_RW( SDL_RWops *src )
/* The 32 last colors are the same but divided by 2 */
/* Some Amiga pictures save 64 colors with 32 last wrong colors, */
/* they shouldn't !, and here we overwrite these 32 bad colors. */
if ( (nbcolors==32 || flagEHB ) && (1<<bmhd.planes)==64 )
if ( (nbcolors==32 || flagEHB ) && (1<<nbplanes)==64 )
{
nbcolors = 64;
ptr = &colormap[0];
Expand All @@ -290,8 +301,8 @@ SDL_Surface *IMG_LoadLBM_RW( SDL_RWops *src )

/* If nbcolors < 2^nbplanes, repeat the colormap */
/* This happens when pictures have a stencil mask */
if ( nbrcolorsfinal > (1<<bmhd.planes) ) {
nbrcolorsfinal = (1<<bmhd.planes);
if ( nbrcolorsfinal > (1<<nbplanes) ) {
nbrcolorsfinal = (1<<nbplanes);
}
for ( i=nbcolors; i < (Uint32)nbrcolorsfinal; i++ )
{
Expand Down Expand Up @@ -365,7 +376,7 @@ SDL_Surface *IMG_LoadLBM_RW( SDL_RWops *src )

/* One line has been read, store it ! */

ptr = Image->pixels;
ptr = (Uint8 *)Image->pixels;
if ( nbplanes==24 || flagHAM==1 )
ptr += h * width * 3;
else
Expand Down
22 changes: 11 additions & 11 deletions IMG_pcx.c
Expand Up @@ -149,8 +149,8 @@ SDL_Surface *IMG_LoadPCX_RW(SDL_RWops *src)
if (bpl > surface->pitch) {
error = "bytes per line is too large (corrupt?)";
}
buf = malloc(bpl);
row = surface->pixels;
buf = (Uint8 *)calloc(SDL_max(bpl, surface->pitch), 1);
row = (Uint8 *)surface->pixels;
for ( y=0; y<surface->h; ++y ) {
/* decode a scan line to a temporary buffer first */
int i, count = 0;
Expand Down Expand Up @@ -184,30 +184,30 @@ SDL_Surface *IMG_LoadPCX_RW(SDL_RWops *src)

if(src_bits <= 4) {
/* expand planes to 1 byte/pixel */
Uint8 *src = buf;
Uint8 *innerSrc = buf;
int plane;
for(plane = 0; plane < pcxh.NPlanes; plane++) {
int i, j, x = 0;
for(i = 0; i < pcxh.BytesPerLine; i++) {
Uint8 byte = *src++;
for(j = 7; j >= 0; j--) {
unsigned bit = (byte >> j) & 1;
int j, k, x = 0;
for(j = 0; j < pcxh.BytesPerLine; j++) {
Uint8 byte = *innerSrc++;
for(k = 7; k >= 0; k--) {
unsigned bit = (byte >> k) & 1;
/* skip padding bits */
if (i * 8 + j >= width)
if (j * 8 + k >= width)
continue;
row[x++] |= bit << plane;
}
}
}
} else if(src_bits == 24) {
/* de-interlace planes */
Uint8 *src = buf;
Uint8 *innerSrc = buf;
int plane;
for(plane = 0; plane < pcxh.NPlanes; plane++) {
int x;
dst = row + plane;
for(x = 0; x < width; x++) {
*dst = *src++;
*dst = *innerSrc++;
dst += pcxh.NPlanes;
}
}
Expand Down
19 changes: 11 additions & 8 deletions IMG_png.c
Expand Up @@ -374,7 +374,7 @@ SDL_Surface *IMG_LoadPNG_RW(SDL_RWops *src)
}
start = SDL_RWtell(src);

if ( !IMG_Init(IMG_INIT_PNG) ) {
if ( (IMG_Init(IMG_INIT_PNG) & IMG_INIT_PNG) == 0 ) {
return NULL;
}

Expand Down Expand Up @@ -444,15 +444,18 @@ SDL_Surface *IMG_LoadPNG_RW(SDL_RWops *src)
&transv);
if(color_type == PNG_COLOR_TYPE_PALETTE) {
/* Check if all tRNS entries are opaque except one */
int i, t = -1;
for(i = 0; i < num_trans; i++)
if(trans[i] == 0) {
if(t >= 0)
int j, t = -1;
for(j = 0; j < num_trans; j++) {
if(trans[j] == 0) {
if (t >= 0) {
break;
t = i;
} else if(trans[i] != 255)
}
t = j;
} else if(trans[j] != 255) {
break;
if(i == num_trans) {
}
}
if(j == num_trans) {
/* exactly one transparent index */
ckey = t;
} else {
Expand Down

0 comments on commit 1c1755e

Please sign in to comment.