Index: src/gifread.c =================================================================== --- src/gifread.c.orig +++ src/gifread.c @@ -20,6 +20,8 @@ #include #include +#include "oversized.h" + #include #include @@ -191,6 +193,9 @@ value dGifGetLine( value hdl ) GifFileType *GifFile = (GifFileType*) hdl; + if( oversized( GifFile->Image.Width, sizeof(GifPixelType) ) ){ + failwith_oversized("gif"); + } buf = alloc_string( GifFile->Image.Width * sizeof(GifPixelType) ); if( DGifGetLine(GifFile, String_val(buf), GifFile->Image.Width ) Index: src/jpegread.c =================================================================== --- src/jpegread.c.orig +++ src/jpegread.c @@ -20,6 +20,8 @@ #include #include +#include "oversized.h" + #include #include @@ -156,6 +158,12 @@ read_JPEG_file (value name) */ /* JSAMPLEs per row in output buffer */ + if( oversized(cinfo.output_width, cinfo.output_components) ){ + jpeg_destroy_decompress(&cinfo); + fclose(infile); + failwith_oversized("jpeg"); + } + row_stride = cinfo.output_width * cinfo.output_components; /* Make a one-row-high sample array that will go away when done with image */ @@ -177,6 +185,12 @@ read_JPEG_file (value name) jpeg_read_scanlines(&cinfo, buffer + cinfo.output_scanline, 1); } + if( oversized(row_stride, cinfo.output_height) ){ + jpeg_destroy_decompress(&cinfo); + fclose(infile); + failwith_oversized("jpeg"); + } + { CAMLlocalN(r,3); r[0] = Val_int(cinfo.output_width); @@ -352,6 +366,7 @@ value open_jpeg_file_for_read_start( jpe { CAMLlocalN(r,3); + // CR jfuruse: integer overflow r[0] = Val_int(cinfop->output_width); r[1] = Val_int(cinfop->output_height); r[2] = alloc_tuple(3); Index: src/oversized.h =================================================================== --- /dev/null +++ src/oversized.h @@ -0,0 +1,9 @@ +#include +/* Test if x or y are negative, or if multiplying x * y would cause an + * arithmetic overflow. + */ +#define oversized(x, y) \ + ((x) < 0 || (y) < 0 || ((y) != 0 && (x) > INT_MAX / (y))) + +#define failwith_oversized(lib) \ + failwith("#lib error: image contains oversized or bogus width and height"); Index: src/pngread.c =================================================================== --- src/pngread.c.orig +++ src/pngread.c @@ -17,6 +17,8 @@ #include +#include "oversized.h" + #include #include #include @@ -81,6 +83,9 @@ value read_png_file_as_rgb24( name ) png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, NULL, NULL); + if (oversized (width, height)) + failwith_oversized("png"); + if ( color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA ) { png_set_gray_to_rgb(png_ptr); @@ -102,10 +107,16 @@ value read_png_file_as_rgb24( name ) rowbytes = png_get_rowbytes(png_ptr, info_ptr); + if (oversized (rowbytes, height)) + failwith_oversized("png"); + { int i; png_bytep *row_pointers; + if (oversized (sizeof (png_bytep), height)) + failwith_oversized("png"); + row_pointers = (png_bytep*) stat_alloc(sizeof(png_bytep) * height); res = alloc_tuple(3); @@ -235,6 +246,9 @@ value read_png_file( name ) png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, NULL, NULL); + if (oversized (width, height)) + failwith_oversized("png"); + if ( color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA ) { png_set_gray_to_rgb(png_ptr); @@ -251,6 +265,9 @@ value read_png_file( name ) rowbytes = png_get_rowbytes(png_ptr, info_ptr); + if (oversized (rowbytes, height)) + failwith_oversized("png"); + /* fprintf(stderr, "pngread.c: actual loading\n"); fflush(stderr); */ @@ -259,6 +276,9 @@ fprintf(stderr, "pngread.c: actual loadi png_bytep *row_pointers; char mesg[256]; + if (oversized (sizeof (png_bytep), height)) + failwith_oversized("png"); + row_pointers = (png_bytep*)stat_alloc(sizeof(png_bytep) * height); res = alloc_tuple(3);