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;