--- vultures/vultures_gfl.c.libpng 2008-07-16 08:59:01.000000000 -0500 +++ vultures/vultures_gfl.c 2012-01-29 00:08:20.845880660 -0600 @@ -22,12 +22,17 @@ #define PNG_BYTES_TO_CHECK 4 +struct readbuff {char *buff; unsigned int len;}; static void vultures_png_read_callback(png_structp png_ptr, png_bytep area, png_size_t size) { - void *mem = png_ptr->io_ptr; - memcpy(area, mem, size); - png_ptr->io_ptr = (mem + size); + unsigned int readlen; + struct readbuff *readfrom = (struct readbuff *)png_get_io_ptr(png_ptr); + readlen = (readfrom->len > size) ? size : readfrom->len; + memcpy(area, readfrom->buff, readlen); + size = readlen; + readfrom->len -= readlen; + readfrom->buff += readlen; } /*-------------------------------------------------------------------------- @@ -45,6 +50,7 @@ int bit_depth, color_type, row; png_bytep * row_pointers = NULL; SDL_Surface *img, *convert; + struct readbuff readfrom; /* vultures_load_surface converts everything to screen format for faster blitting * so we can't continue if we don't have a screen yet */ @@ -55,6 +61,9 @@ if (!srcbuf) return NULL; + if (buflen < PNG_BYTES_TO_CHECK) + return NULL; + img = NULL; /* memory region must contain a png file */ @@ -72,10 +81,13 @@ goto out; /* Set up error handling */ - if (setjmp(png_ptr->jmpbuf)) + if (setjmp(png_jmpbuf(png_ptr))) goto out; - png_set_read_fn(png_ptr, (char *)srcbuf, vultures_png_read_callback); + readfrom.buff = (char *)srcbuf; + readfrom.len = buflen; + + png_set_read_fn(png_ptr, &readfrom, vultures_png_read_callback); /* Read PNG header info */ png_read_info(png_ptr, info_ptr); @@ -93,8 +105,9 @@ png_set_gray_to_rgb(png_ptr); /* add an opaque alpha channel to anything that doesn't have one yet */ - png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER); - info_ptr->color_type |= PNG_COLOR_MASK_ALPHA; + if (png_get_color_type(png_ptr, info_ptr) == PNG_COLOR_TYPE_RGB || + png_get_color_type(png_ptr, info_ptr) == PNG_COLOR_TYPE_GRAY) + png_set_add_alpha(png_ptr, 0xff, PNG_FILLER_AFTER); /* get the component mask for the surface */ if ( SDL_BYTEORDER == SDL_LIL_ENDIAN )