This is an automated email from the git hooks/post-receive script. ecsv-guest pushed a commit to branch master in repository mupen64plus.
commit 55f1f6e5f9d6e67fc3a3c3413d6f9c92146e6cdb Author: Sven Eckelmann <[email protected]> Date: Mon Sep 21 22:24:46 2009 +0200 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. --- debian/changelog | 2 + debian/patches/fix_readpng.patch | 291 +++++++++++++++++++++++++++++++++++++++ debian/patches/series | 1 + 3 files changed, 294 insertions(+) diff --git a/debian/changelog b/debian/changelog index 0ad302e..3fc174f 100644 --- a/debian/changelog +++ b/debian/changelog @@ -7,6 +7,8 @@ mupen64plus (1.5+dfsg1-5) UNRELEASED; urgency=low filtered open file dialog (Closes: #546046) - Add noexecstack.patch, Don't enable executable stack by default (Closes: #547644) + - Add fix_readpng.patch, Fix crash when loading png due to reordering + optimizer -- Sven Eckelmann <[email protected]> Fri, 11 Sep 2009 00:37:19 +0200 diff --git a/debian/patches/fix_readpng.patch b/debian/patches/fix_readpng.patch new file mode 100644 index 0000000..d44b219 --- /dev/null +++ b/debian/patches/fix_readpng.patch @@ -0,0 +1,291 @@ +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. +Bug: http://code.google.com/p/mupen64plus/issues/detail?id=209 +Author: Sven Eckelmann <[email protected]> + +--- +diff --git a/rice_video/liblinux/bmp.c b/rice_video/liblinux/bmp.c +index 13c66fdc427c6fc94bff5e3434a1067199d7353f..877e376d1f3c59228027330375f9b40090ef8cef 100644 +--- a/rice_video/liblinux/bmp.c ++++ b/rice_video/liblinux/bmp.c +@@ -206,7 +206,6 @@ BMGError WriteBMP( const char *filename, + struct BMGImageStruct img ) + { + FILE *file = NULL; +- jmp_buf err_jmp; + int error; + + unsigned char *bits = NULL; +@@ -223,30 +222,24 @@ BMGError WriteBMP( const char *filename, + + SetLastBMGError( BMG_OK ); + +- /* error handler */ +- error = setjmp( err_jmp ); +- if ( error != 0 ) +- { +- if ( file != NULL ) +- fclose( file ); +- if ( bits != NULL ) +- free( bits ); +- if ( pColor != NULL ) +- free( pColor ); +- SetLastBMGError( (BMGError)error ); +- return (BMGError)error; ++ if ( img.bits == NULL ) { ++ SetLastBMGError( errInvalidBMGImage ); ++ return errInvalidBMGImage; + } + +- if ( img.bits == NULL ) +- longjmp( err_jmp, (int)errInvalidBMGImage ); +- + file = fopen( filename, "wb" ); +- if ( file == NULL ) +- longjmp( err_jmp, (int)errFileOpen ); ++ if ( file == NULL ) { ++ fclose( file ); ++ SetLastBMGError( errFileOpen ); ++ return errFileOpen; ++ } + + /* abort if we do not support the data */ +- if ( img.palette != NULL && img.bytes_per_palette_entry < 3 ) +- longjmp( err_jmp, (int)errInvalidBMGImage ); ++ if ( img.palette != NULL && img.bytes_per_palette_entry < 3 ) { ++ fclose( file ); ++ SetLastBMGError( errInvalidBMGImage ); ++ return errInvalidBMGImage; ++ } + + /* calculate dimensions */ + BitsPerPixel = img.bits_per_pixel < 32 ? img.bits_per_pixel : 24U; +@@ -259,8 +252,11 @@ BMGError WriteBMP( const char *filename, + /* allocate memory for bit array - assume that compression will + // actually compress the bitmap */ + bits = (unsigned char *)calloc( bit_size, 1 ); +- if ( bits == NULL ) +- longjmp( err_jmp, (int)errMemoryAllocation ); ++ if ( bits == NULL ) { ++ fclose( file ); ++ SetLastBMGError( errMemoryAllocation ); ++ return errMemoryAllocation; ++ } + + /* some initialization */ + memset( (void *)&bmih, 0, sizeof(BITMAPINFOHEADER) ); +@@ -312,8 +308,12 @@ BMGError WriteBMP( const char *filename, + if ( img.palette != NULL ) + { + pColor = (unsigned char *)calloc( img.palette_size, sizeof(RGBQUAD) ); +- if ( pColor == NULL ) +- longjmp( err_jmp, (int)errMemoryAllocation ); ++ if ( pColor == NULL ) { ++ free( bits ); ++ fclose( file ); ++ SetLastBMGError( errMemoryAllocation ); ++ return errMemoryAllocation; ++ } + + if ( img.bytes_per_palette_entry == 3 ) + { +@@ -338,31 +338,43 @@ BMGError WriteBMP( const char *filename, + img.palette_size * sizeof(RGBQUAD); + bmfh.bfSize = bmfh.bfOffBits + bit_size; + +- if ( fwrite( (void *)&bmfh, sizeof(BITMAPFILEHEADER), 1, file ) != 1 ) +- longjmp( err_jmp, (int)errFileWrite ); ++ if ( fwrite( (void *)&bmfh, sizeof(BITMAPFILEHEADER), 1, file ) != 1 ) { ++ free( pColor ); ++ free( bits ); ++ fclose( file ); ++ SetLastBMGError( errFileWrite ); ++ return errFileWrite; ++ } + +- if ( fwrite( (void *)&bmih, sizeof(BITMAPINFOHEADER), 1, file ) != 1 ) +- longjmp( err_jmp, (int)errFileWrite ); ++ if ( fwrite( (void *)&bmih, sizeof(BITMAPINFOHEADER), 1, file ) != 1 ) { ++ free( pColor ); ++ free( bits ); ++ fclose( file ); ++ SetLastBMGError( errFileWrite ); ++ return errFileWrite; ++ } + +- if ( pColor != NULL ) +- { +- if ( fwrite( (void *)pColor, sizeof(RGBQUAD), img.palette_size, file ) +- != (unsigned int)img.palette_size ) +- { +- longjmp( err_jmp, (int)errFileWrite ); +- } ++ if ( fwrite( (void *)pColor, sizeof(RGBQUAD), img.palette_size, file ) ++ != (unsigned int)img.palette_size ) { ++ free( pColor ); ++ free( bits ); ++ fclose( file ); ++ SetLastBMGError( errFileWrite ); ++ return errFileWrite; + } + + if ( fwrite( (void *)bits, sizeof(unsigned char), bit_size, file ) +- != bit_size ) +- { +- longjmp( err_jmp, (int)errFileWrite ); ++ != bit_size ) { ++ free( pColor ); ++ free( bits ); ++ fclose( file ); ++ SetLastBMGError( errFileWrite ); ++ return errFileWrite; + } + + fclose( file ); + free( bits ); +- if ( pColor != NULL ) +- free( pColor ); ++ free( pColor ); + return BMG_OK; + } + +diff --git a/rice_video/liblinux/pngrw.c b/rice_video/liblinux/pngrw.c +index 673741adbc1d75499100624572a6512fdefd39dc..e9985e873b9280670b5c11fb848833ac5b37713e 100644 +--- a/rice_video/liblinux/pngrw.c ++++ b/rice_video/liblinux/pngrw.c +@@ -109,13 +109,14 @@ BMGError ReadPNG( const char *filename, + unsigned char signature[8]; + png_structp png_ptr = NULL; + png_infop info_ptr = NULL; ++ png_infop 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; +@@ -128,53 +129,63 @@ BMGError ReadPNG( const char *filename, + BMGError tmp; + unsigned int DIBLineWidth; + +- /* error handler */ +- error = setjmp( err_jmp ); +- if ( error != 0 ) +- { +- if ( png_ptr != NULL ) +- png_destroy_read_struct( &png_ptr, NULL, NULL ); +- if ( rows ) +- { +- if ( rows[0] ) +- free( rows[0] ); +- free( rows ); +- } +- FreeBMGImage( img ); +- fclose( file ); +- SetLastBMGError( (BMGError)error ); ++ if ( img == NULL ) { ++ SetLastBMGError( errInvalidBMGImage ); + return (BMGError)error; + } + +- if ( img == NULL ) +- longjmp ( err_jmp, (int)errInvalidBMGImage ); +- + file = fopen( filename, "rb" ); +- if ( !file ) +- longjmp ( err_jmp, (int)errFileOpen ); ++ if ( !file ) { ++ SetLastBMGError( errFileOpen ); ++ return errFileOpen; ++ } + + /* check the signature */ + fread( signature, 1, 8, file ); +- if ( !png_check_sig( signature, 8 ) ) +- longjmp( err_jmp, (int)errUnsupportedFileFormat ); ++ if ( !png_check_sig( signature, 8 ) ) { ++ fclose(file); ++ SetLastBMGError( errUnsupportedFileFormat ); ++ return errUnsupportedFileFormat; ++ } + + /* create a pointer to the png read structure */ + png_ptr = png_create_read_struct( PNG_LIBPNG_VER_STRING, NULL, NULL, NULL ); +- if ( !png_ptr ) +- longjmp( err_jmp, (int)errMemoryAllocation ); ++ if ( !png_ptr ) { ++ fclose(file); ++ SetLastBMGError( errMemoryAllocation ); ++ return errMemoryAllocation; ++ } ++ ++ /* create a pointer to the png info structure */ ++ info_ptr = png_create_info_struct( png_ptr ); ++ if ( !info_ptr ) { ++ fclose(file); ++ png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL); ++ SetLastBMGError( errMemoryAllocation ); ++ return errMemoryAllocation; ++ } ++ ++ end_info = png_create_info_struct(png_ptr); ++ if (!end_info) ++ { ++ png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL); ++ SetLastBMGError( errMemoryAllocation ); ++ return errMemoryAllocation; ++ } + + /* bamboozle the PNG longjmp buffer */ + /*generic PNG error handler*/ + /* error will always == 1 which == errLib */ + // error = png_setjmp(png_ptr); +- error = setjmp( png_jmpbuf( png_ptr ) ); +- 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 ); ++ error = setjmp(png_jmpbuf(png_ptr)); ++ if ( error != 0 ) ++ { ++ png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); ++ FreeBMGImage( img ); ++ fclose( file ); ++ SetLastBMGError( (BMGError)error ); ++ return (BMGError)error; ++ } + + /* attach file buffer to the png read pointer */ + png_init_io( png_ptr, file ); +@@ -187,7 +198,7 @@ BMGError ReadPNG( const char *filename, + + /* extract the data we need to form the HBITMAP from the PNG header */ + png_get_IHDR( png_ptr, info_ptr, &Width, &Height, &BitDepth, &ColorType, +- &InterlaceType, NULL, NULL ); ++ &InterlaceType, int_p_NULL, int_p_NULL ); + + img->width = Width; + img->height = Height; +@@ -356,8 +367,10 @@ BMGError ReadPNG( const char *filename, + + k = png_get_rowbytes( png_ptr, info_ptr ); + rows[0] = (unsigned char *)malloc( Height*k*sizeof(char)); +- if ( !rows[0] ) ++ if ( !rows[0] ) { ++ free( rows ); + longjmp( err_jmp, (int)errMemoryAllocation ); ++ } + + for ( i = 1; i < (int)Height; i++ ) + rows[i] = rows[i-1] + k; diff --git a/debian/patches/series b/debian/patches/series index ab3d2a8..51573fd 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -23,3 +23,4 @@ version-string.patch default-optimisations.patch gtk-open-filter.patch noexecstack.patch +fix_readpng.patch -- Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-games/mupen64plus.git _______________________________________________ Pkg-games-commits mailing list [email protected] http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pkg-games-commits

