File optipng-CVE-2008-5101.patch of Package optipng

diff -ru optipng-0.6.1/lib/pngxtern/pngx.h optipng-0.6.1.1/lib/pngxtern/pngx.h
--- optipng-0.6.1/lib/pngxtern/pngx.h	2008-04-21 09:25:00.000000000 -0400
+++ optipng-0.6.1.1/lib/pngxtern/pngx.h	2008-11-04 09:09:00.000000000 -0500
@@ -41,6 +41,14 @@
    PNGARG((png_structp png_ptr, png_infop info_ptr, int interlace_method));
 
 
+#if PNG_LIBPNG_VER >= 10400
+typedef png_alloc_size_t pngx_alloc_size_t;
+#else
+/* Compatibility backport of png_alloc_size_t */
+typedef png_uint_32 pngx_alloc_size_t;
+#endif
+
+#ifdef PNG_INFO_IMAGE_SUPPORTED
 /* Allocate memory for the row pointers.
  * Use filler to initialize the rows if it is non-negative.
  * On success return the newly-allocated row pointers.
@@ -49,6 +57,10 @@
  */
 extern PNG_EXPORT(png_bytepp, pngx_malloc_rows)
    PNGARG((png_structp png_ptr, png_infop info_ptr, int filler));
+extern PNG_EXPORT(png_bytepp, pngx_malloc_rows_extended)
+   PNGARG((png_structp png_ptr, png_infop info_ptr,
+           pngx_alloc_size_t min_row_size, int filler));
+#endif
 
 
 #if PNG_LIBPNG_VER >= 10400
@@ -77,9 +89,9 @@
 #else /* PNG_LIBPNG_VER < 10400 */
 
 /* Compatibility backports of functions added to libpng 1.4 */
-extern PNG_EXPORT(png_uint_32,pngx_get_io_state)
+extern PNG_EXPORT(png_uint_32, pngx_get_io_state)
    PNGARG((png_structp png_ptr));
-extern PNG_EXPORT(png_bytep,pngx_get_io_chunk_name)
+extern PNG_EXPORT(png_bytep, pngx_get_io_chunk_name)
    PNGARG((png_structp png_ptr));
 /* Note: although these backports have several limitations in comparison
  * to the actual libpng 1.4 functions, they work properly in OptiPNG,
@@ -87,11 +99,11 @@
  */
 
 /* Compatibility wrappers for old libpng functions */
-extern PNG_EXPORT(void,pngx_set_read_fn) PNGARG((png_structp png_ptr,
+extern PNG_EXPORT(void, pngx_set_read_fn) PNGARG((png_structp png_ptr,
    png_voidp io_ptr, png_rw_ptr read_data_fn));
-extern PNG_EXPORT(void,pngx_set_write_fn) PNGARG((png_structp png_ptr,
+extern PNG_EXPORT(void, pngx_set_write_fn) PNGARG((png_structp png_ptr,
    png_voidp io_ptr, png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn));
-extern PNG_EXPORT(void,pngx_write_sig) PNGARG((png_structp png_ptr));
+extern PNG_EXPORT(void, pngx_write_sig) PNGARG((png_structp png_ptr));
 
 /* Flags returned by png_get_io_state() */
 #define PNGX_IO_NONE        0x0000  /* no I/O at this moment */
diff -ru optipng-0.6.1/lib/pngxtern/pngxio.c optipng-0.6.1.1/lib/pngxtern/pngxio.c
--- optipng-0.6.1/lib/pngxtern/pngxio.c	2008-06-17 19:42:00.000000000 -0400
+++ optipng-0.6.1.1/lib/pngxtern/pngxio.c	2008-10-16 20:03:00.000000000 -0400
@@ -5,12 +5,13 @@
  * This software is distributed under the same licensing and warranty terms
  * as libpng.
  *
- * CAUTION:
- * Currently, these functions have a limited and thread-unsafe
- * implementation that allows only one reading and one writing png_ptr.
- * They are now part of libpng starting with libpng-1.4.0.
- * Their libpng counterparts are much simpler, as well as thread-safe,
- * due to the presence of io_state inside png_struct.
+ * NOTE:
+ * The functionality provided in this module has "graduated", and is now
+ * part of libpng-1.4.  The original code is used here as a back-port, for
+ * compatibility with libpng-1.2 and earlier.  However, it has limitations:
+ * is thread-unsafe and only supports one reading and one writing png_ptr.
+ * (The libpng-1.4 code is much simpler and does not have these limitations,
+ * due to the presence of io_state inside png_struct.)
  *
  * For more info, see pngx.h.
  */
@@ -156,8 +157,8 @@
 }
 
 
-/* In libpng-1.4, the proper implementation if this function
- * simply retrieves png_ptr->io_state.
+/* In libpng-1.4, the implementation of this function simply retrieves
+ * png_ptr->io_state.
  */
 png_uint_32 PNGAPI
 pngx_get_io_state(png_structp png_ptr)
@@ -173,8 +174,8 @@
    return PNGX_IO_NONE;
 }
 
-/* In libpng-1.4, the proper implementation if this function
- * simply retrieves png_ptr->chunk_name.
+/* In libpng-1.4, the implementation of this function simply retrieves
+ * png_ptr->chunk_name.
  */
 png_bytep PNGAPI
 pngx_get_io_chunk_name(png_structp png_ptr)
@@ -218,8 +219,11 @@
 void PNGAPI
 pngx_write_sig(png_structp png_ptr)
 {
-#if (PNG_LIBPNG_BUILD_TYPE & PNG_LIBPNG_BUILD_PRIVATE)
+#if 0  /* png_write_sig is not exported from libpng-1.2. */
    png_write_sig(png_ptr);
+   /* TODO: Add png_write_sig to the list of libpng-1.2 exports.
+    * This would complement well the group png_write_chunk{_start,_data,_end}.
+    */
 #else
    static png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10};
    pngx_priv_read_write(png_ptr, png_signature, 8);
diff -ru optipng-0.6.1/lib/pngxtern/pngxmem.c optipng-0.6.1.1/lib/pngxtern/pngxmem.c
--- optipng-0.6.1/lib/pngxtern/pngxmem.c	2008-04-21 09:14:00.000000000 -0400
+++ optipng-0.6.1.1/lib/pngxtern/pngxmem.c	2008-11-04 09:18:00.000000000 -0500
@@ -11,36 +11,43 @@
 #include "pngx.h"
 
 
-#if PNG_LIBPNG_VER < 10400
-typedef png_uint_32 png_alloc_size_t;
-/* Since libpng-1.4.x, png_alloc_size_t is either png_size_t or png_uint_32,
- * whichever is larger.
- */
-#endif
+#ifdef PNG_INFO_IMAGE_SUPPORTED
 
 
 png_bytepp PNGAPI
 pngx_malloc_rows(png_structp png_ptr, png_infop info_ptr, int filler)
 {
+   return pngx_malloc_rows_extended(png_ptr, info_ptr, 0, filler);
+}
+
+
+png_bytepp PNGAPI
+pngx_malloc_rows_extended(png_structp png_ptr, png_infop info_ptr,
+   pngx_alloc_size_t min_row_size, int filler)
+{
+   pngx_alloc_size_t row_size;
    png_bytep row;
    png_bytepp rows;
-   png_alloc_size_t row_size;
    png_uint_32 height, i;
 
+   /* Calculate the row size. */
+   row_size = png_get_rowbytes(png_ptr, info_ptr);
+   if (row_size == 0)
+      return NULL;
+   if (row_size < min_row_size)
+      row_size = min_row_size;
+
    /* Deallocate the currently-existing rows. */
-#ifdef PNG_FREE_ME_SUPPORTED
    png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0);
-#endif
 
    /* Allocate memory for the row index. */
    height = png_get_image_height(png_ptr, info_ptr);
    rows = (png_bytepp)png_malloc(png_ptr,
-      (png_alloc_size_t)(height * sizeof(png_bytep)));
+      (pngx_alloc_size_t)(height * sizeof(png_bytep)));
    if (rows == NULL)
       return NULL;
 
    /* Allocate memory for each row. */
-   row_size = png_get_rowbytes(png_ptr, info_ptr);
    for (i = 0; i < height; ++i)
    {
       row = (png_bytep)png_malloc(png_ptr, row_size);
@@ -61,3 +68,15 @@
    png_set_rows(png_ptr, info_ptr, rows);
    return rows;
 }
+
+
+#if 0  /* not necessary */
+void PNGAPI
+pngx_free_rows(png_structp png_ptr, png_infop info_ptr)
+{
+   png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0);
+}
+#endif
+
+
+#endif /* PNG_INFO_IMAGE_SUPPORTED */
diff -ru optipng-0.6.1/lib/pngxtern/pngxrbmp.c optipng-0.6.1.1/lib/pngxtern/pngxrbmp.c
--- optipng-0.6.1/lib/pngxtern/pngxrbmp.c	2008-05-10 18:21:00.000000000 -0400
+++ optipng-0.6.1.1/lib/pngxtern/pngxrbmp.c	2008-11-04 09:45:00.000000000 -0500
@@ -13,11 +13,9 @@
 #include <string.h>
 
 
-/**
- * BMP file header macros
- * Public domain by MIYASAKA Masaru
- * Updated by Cosmin Truta
- **/
+/*****************************************************************************/
+/* BMP file header macros                                                    */
+/*****************************************************************************/
 
 /* BMP file signature */
 #define BMP_SIGNATURE       0x4d42  /* "BM" */
@@ -482,7 +480,7 @@
    png_bytep const bih = bfh + FILEHED_SIZE;
    png_byte rgbq[RGBQUAD_SIZE];
    png_uint_32 offbits, bihsize, skip;
-   png_uint_32 width, height;
+   png_uint_32 width, height, rowsize;
    int topdown;
    unsigned int pixdepth;
    png_uint_32 compression;
@@ -492,7 +490,6 @@
    int bit_depth, color_type;
    png_color palette[256];
    png_color_8 sig_bit;
-   png_size_t rowsize, rowbytes;
    png_bytepp row_pointers, begin_row, end_row;
    unsigned int i;
    png_size_t y;
@@ -531,7 +528,7 @@
          return 0;
    skip = offbits - bihsize - FILEHED_SIZE;  /* new skip */
    topdown = 0;
-   if (bihsize == COREHED_SIZE)  /* OS/2 BMP */
+   if (bihsize < INFOHED_SIZE)  /* OS/2 BMP */
    {
       width       = bmp_get_word(bih + BCH_WWIDTH);
       height      = bmp_get_word(bih + BCH_WHEIGHT);
@@ -539,7 +536,7 @@
       compression = BI_RGB;
       palsize     = RGBTRIPLE_SIZE;
    }
-   else  /* bihsize >= INFOHED_SIZE: Windows BMP */
+   else  /* Windows BMP */
    {
       width       = bmp_get_dword(bih + BIH_LWIDTH);
       height      = bmp_get_dword(bih + BIH_LHEIGHT);
@@ -551,19 +548,20 @@
          height  = PNG_UINT_32_MAX - height + 1;
          topdown = 1;
       }
+      if (bihsize == INFOHED_SIZE && compression == BI_BITFIELDS)
+      {
+         /* Read the RGB[A] mask. */
+         i = (skip <= 16) ? (unsigned int)skip : 16;
+         if (fread(bih + B4H_DREDMASK, i, 1, stream) != 1)
+            return 0;
+         bihsize += i;
+         skip -= i;
+      }
    }
 
    png_memset(rgba_mask, 0, sizeof(rgba_mask));
    if (pixdepth > 8)
    {
-      if (bihsize <= INFOHED_SIZE)
-         png_memset(bih + B4H_DREDMASK, 0, 16);
-      if (bihsize == INFOHED_SIZE && skip >= 12)
-      {
-         if (fread(bih + B4H_DREDMASK, 12, 1, stream) != 1)
-            bihsize = 0;
-         skip -= 12;
-      }
       if (compression == BI_RGB)
       {
          if (pixdepth == 16)
@@ -582,11 +580,17 @@
       }
       else if (compression == BI_BITFIELDS)
       {
-         rgba_mask[0] = bmp_get_dword(bih + B4H_DREDMASK);
-         rgba_mask[1] = bmp_get_dword(bih + B4H_DGREENMASK);
-         rgba_mask[2] = bmp_get_dword(bih + B4H_DBLUEMASK);
+         if (bihsize >= INFOHED_SIZE + 12)
+         {
+            rgba_mask[0] = bmp_get_dword(bih + B4H_DREDMASK);
+            rgba_mask[1] = bmp_get_dword(bih + B4H_DGREENMASK);
+            rgba_mask[2] = bmp_get_dword(bih + B4H_DBLUEMASK);
+         }
+         else
+            png_error(png_ptr, "Missing color mask in BMP file");
       }
-      rgba_mask[3] = bmp_get_dword(bih + B4H_DALPHAMASK);
+      if (bihsize >= INFOHED_SIZE + 16)
+         rgba_mask[3] = bmp_get_dword(bih + B4H_DALPHAMASK);
    }
 
    switch (compression)
@@ -637,7 +641,8 @@
       if (palnum > 256)
          palnum = 256;
       skip -= palsize * palnum;
-      rowsize = rowbytes = (width + (32 / pixdepth) - 1) / (32 / pixdepth) * 4;
+      rowsize = (width + (32 / pixdepth) - 1) / (32 / pixdepth) * 4;
+      /* rowsize becomes 0 on overflow. */
       bit_depth = pixdepth;
       color_type = (palnum > 0) ? PNG_COLOR_TYPE_PALETTE : PNG_COLOR_TYPE_GRAY;
    }
@@ -645,28 +650,28 @@
    {
       palnum = 0;
       bit_depth = 8;
-      if (width > (png_size_t)(-4) / (pixdepth / 8))
-         png_error(png_ptr, "Can't handle exceedingly large BMP dimensions");
-      /* Overflow in rowbytes is checked inside png_set_IHDR(). */
       switch (pixdepth)
       {
       case 16:
-         rowsize  = (png_size_t)((width * 2 + 3) & (~3));
-         rowbytes = (width * 3 + 3) & (~3);
+         rowsize = (width * 2 + 3) & (~3);
          break;
       case 24:
-         rowbytes = rowsize = (png_size_t)((width * 3 + 3) & (~3));
+         rowsize = (width * 3 + 3) & (~3);
          break;
       case 32:
-         rowbytes = rowsize = (png_size_t)(width * 4);
+         rowsize = width * 4;
          break;
       default:  /* never get here */
          bit_depth = 0;
-         rowbytes = rowsize = 0;
+         rowsize = 0;
       }
+      if (rowsize / width < pixdepth / 8)
+         rowsize = 0;  /* overflow */
       color_type = (rgba_mask[3] != 0) ?
          PNG_COLOR_TYPE_RGBA : PNG_COLOR_TYPE_RGB;
    }
+   if (rowsize == 0)
+      png_error(png_ptr, "Exceedingly large image dimensions in BMP file");
 
    /* Set the PNG image type. */
    png_set_IHDR(png_ptr, info_ptr,
@@ -706,7 +711,7 @@
    }
 
    /* Allocate memory and read the image data. */
-   row_pointers = pngx_malloc_rows(png_ptr, info_ptr, -1);
+   row_pointers = pngx_malloc_rows_extended(png_ptr, info_ptr, rowsize, -1);
    if (topdown)
    {
       begin_row = row_pointers;
openSUSE Build Service is sponsored by