Description: Fix crash when loading png due to reordering optimizer The optimizer can reorder instructions like the initialisation of variables if it looks safe to him. It isn't said that all variables are initialised right before the call of the first setjmp and thus we cannot rely on there value to determine if they are point to actual data. Origin: backport, commit:1411 Bug: http://code.google.com/p/mupen64plus/issues/detail?id=209 Author: Sven Eckelmann Author: Richard Goedeken --- diff --git a/rice_video/liblinux/bmp.c b/rice_video/liblinux/bmp.c index 13c66fdc427c6fc94bff5e3434a1067199d7353f..f941b2cff8d2a6731d2eca7d8493343ab74b9312 100644 --- a/rice_video/liblinux/bmp.c +++ b/rice_video/liblinux/bmp.c @@ -205,18 +205,18 @@ err_jmp: BMGError WriteBMP( const char *filename, struct BMGImageStruct img ) { - FILE *file = NULL; + FILE * volatile file = NULL; jmp_buf err_jmp; int error; - unsigned char *bits = NULL; + unsigned char * volatile bits = NULL; unsigned int DIBScanWidth; unsigned int BitsPerPixel; unsigned int bit_size; /*, new_bit_size; */ /* unsigned int rawbit_size; */ unsigned char *p, *q, *r, *t; /* unsigned int cnt; */ - unsigned char *pColor = NULL; + unsigned char * volatile pColor = NULL; BITMAPFILEHEADER bmfh; BITMAPINFOHEADER bmih; diff --git a/rice_video/liblinux/pngrw.c b/rice_video/liblinux/pngrw.c index 673741adbc1d75499100624572a6512fdefd39dc..8a103e7aefd10c50c542727310b6efe82c8fda2f 100644 --- a/rice_video/liblinux/pngrw.c +++ b/rice_video/liblinux/pngrw.c @@ -94,12 +94,12 @@ Comments: gray scale images with alpha components are converted to 32-bit images */ BMGError ReadPNG( const char *filename, - struct BMGImageStruct *img ) + struct BMGImageStruct * volatile img ) { jmp_buf err_jmp; int error; - FILE *file = NULL; + FILE * volatile file = NULL; int BitDepth; int BitsPerPixel; int FixedBitDepth; @@ -107,18 +107,19 @@ BMGError ReadPNG( const char *filename, int ImageChannels; int InterlaceType; unsigned char signature[8]; - png_structp png_ptr = NULL; - png_infop info_ptr = NULL; + png_structp volatile png_ptr = NULL; + png_infop volatile info_ptr = NULL; + png_infop volatile end_info = NULL; png_colorp PNGPalette = NULL; png_color_16 *ImageBackground = NULL; png_bytep trns = NULL; int NumTrans = 0; int i, j, k; png_color_16p TransColors = NULL; - unsigned int Width, Height; + png_uint_32 Width, Height; unsigned char *bits, *p, *q; - unsigned char** rows = NULL; + unsigned char** volatile rows = NULL; int NumColors = 0; unsigned char BgdRed = 0; unsigned char BgdGreen = 0; @@ -132,16 +133,22 @@ BMGError ReadPNG( const char *filename, error = setjmp( err_jmp ); if ( error != 0 ) { - if ( png_ptr != NULL ) - png_destroy_read_struct( &png_ptr, NULL, NULL ); + if ( end_info != NULL ) + png_destroy_read_struct((png_structp *) &png_ptr, (png_infop *) &info_ptr, (png_infop *) &end_info); + else if (info_ptr != NULL) + png_destroy_read_struct((png_structp *) &png_ptr, (png_infop *) &info_ptr, NULL); + else if (png_ptr != NULL) + png_destroy_read_struct((png_structp *) &png_ptr, NULL, NULL); if ( rows ) { if ( rows[0] ) free( rows[0] ); free( rows ); } - FreeBMGImage( img ); - fclose( file ); + if (img) + FreeBMGImage(img); + if (file) + fclose(file); SetLastBMGError( (BMGError)error ); return (BMGError)error; } @@ -155,7 +162,7 @@ BMGError ReadPNG( const char *filename, /* check the signature */ fread( signature, 1, 8, file ); - if ( !png_check_sig( signature, 8 ) ) + if ( png_sig_cmp( signature, 0, 8 ) ) longjmp( err_jmp, (int)errUnsupportedFileFormat ); /* create a pointer to the png read structure */ @@ -163,6 +170,16 @@ BMGError ReadPNG( const char *filename, if ( !png_ptr ) longjmp( err_jmp, (int)errMemoryAllocation ); + /* create a pointer to the png info structure */ + info_ptr = png_create_info_struct( png_ptr ); + if ( !info_ptr ) + longjmp( err_jmp, (int)errMemoryAllocation ); + + /* create a pointer to the png end-info structure */ + end_info = png_create_info_struct(png_ptr); + if (!end_info) + longjmp( err_jmp, (int)errMemoryAllocation ); + /* bamboozle the PNG longjmp buffer */ /*generic PNG error handler*/ /* error will always == 1 which == errLib */ @@ -171,11 +188,6 @@ BMGError ReadPNG( const char *filename, if ( error > 0 ) longjmp( err_jmp, error ); - /* create a pointer to the png info structure */ - info_ptr = png_create_info_struct( png_ptr ); - if ( !info_ptr ) - longjmp( err_jmp, (int)errMemoryAllocation ); - /* attach file buffer to the png read pointer */ png_init_io( png_ptr, file ); @@ -475,7 +487,7 @@ BMGError ReadPNG( const char *filename, free( rows[0] ); free( rows ); png_read_end( png_ptr, info_ptr ); - png_destroy_read_struct( &png_ptr, &info_ptr, NULL ); + png_destroy_read_struct((png_structp *) &png_ptr, (png_infop *) &info_ptr, (png_infop *) &end_info); fclose( file ); return BMG_OK;