Blob Blame History Raw
--- 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 )