mirror of
https://git.code.sf.net/p/libpng/code.git
synced 2025-07-10 18:04:09 +02:00
[libpng16] Added code to validate the windowBits value passed to deflateInit2().
If the call to deflateInit2() is wrong a png_warning will be issued (in fact this is harmless, but the PNG data produced may be sub-optimal).
This commit is contained in:
committed by
Glenn Randers-Pehrson
parent
d072048925
commit
6225b0e61e
48
pngwutil.c
48
pngwutil.c
@@ -305,7 +305,11 @@ png_deflate_claim(png_structrp png_ptr, int for_IDAT,
|
||||
}
|
||||
|
||||
/* Adjust 'windowBits' down if larger than 'data_size'; to stop this
|
||||
* happening just pass 32768 as the data_size parameter.
|
||||
* happening just pass 32768 as the data_size parameter. Notice that zlib
|
||||
* requires an extra 262 bytes in the window in addition to the data to be
|
||||
* able to see the whole of the data, so if data_size+262 takes us to the
|
||||
* next windowBits size we need to fix up the value later. (Because even
|
||||
* though deflate needs the extra window, inflate does not!)
|
||||
*/
|
||||
if (data_size <= 256)
|
||||
windowBits = 8;
|
||||
@@ -318,6 +322,20 @@ png_deflate_claim(png_structrp png_ptr, int for_IDAT,
|
||||
--windowBits;
|
||||
}
|
||||
|
||||
if (windowBits < 15)
|
||||
{
|
||||
png_uint_32 test = 1U << windowBits;
|
||||
|
||||
if (data_size + 262U > test)
|
||||
{
|
||||
++windowBits;
|
||||
png_ptr->flags |= PNG_FLAG_ZSTREAM_CMF_FIXUP;
|
||||
}
|
||||
|
||||
else
|
||||
png_ptr->flags &= ~PNG_FLAG_ZSTREAM_CMF_FIXUP;
|
||||
}
|
||||
|
||||
/* Check against the previous initialized values, if any. */
|
||||
if ((png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED) &&
|
||||
(png_ptr->zlib_set_level != level ||
|
||||
@@ -630,6 +648,7 @@ png_write_compressed_data_out(png_structrp png_ptr, compression_state *comp)
|
||||
{
|
||||
unsigned int z_cinfo;
|
||||
unsigned int half_z_window_size;
|
||||
int reduced = 0;
|
||||
png_size_t uncompressed_text_size = comp->input_len;
|
||||
|
||||
z_cinfo = z_cmf >> 4;
|
||||
@@ -640,8 +659,12 @@ png_write_compressed_data_out(png_structrp png_ptr, compression_state *comp)
|
||||
{
|
||||
z_cinfo--;
|
||||
half_z_window_size >>= 1;
|
||||
reduced = 1;
|
||||
}
|
||||
|
||||
if (reduced && !(png_ptr->flags & PNG_FLAG_ZSTREAM_CMF_FIXUP))
|
||||
png_warning(png_ptr, "internal data size error (text)");
|
||||
|
||||
z_cmf = (z_cmf & 0x0f) | (z_cinfo << 4);
|
||||
|
||||
if (comp->num_output_ptr)
|
||||
@@ -960,25 +983,10 @@ png_write_IDAT(png_structrp png_ptr, png_bytep data, png_size_t length)
|
||||
if (length >= 2 &&
|
||||
png_ptr->height < 16384 && png_ptr->width < 16384)
|
||||
{
|
||||
/* Compute the maximum possible length of the datastream */
|
||||
|
||||
/* Number of pixels, plus for each row a filter byte
|
||||
* and possibly a padding byte, so increase the maximum
|
||||
* size to account for these.
|
||||
*/
|
||||
unsigned int z_cinfo;
|
||||
unsigned int half_z_window_size;
|
||||
png_uint_32 uncompressed_idat_size = png_ptr->height *
|
||||
((png_ptr->width *
|
||||
png_ptr->channels * png_ptr->bit_depth + 15) >> 3);
|
||||
|
||||
/* If it's interlaced, each block of 8 rows is sent as up to
|
||||
* 14 rows, i.e., 6 additional rows, each with a filter byte
|
||||
* and possibly a padding byte
|
||||
*/
|
||||
if (png_ptr->interlaced)
|
||||
uncompressed_idat_size += ((png_ptr->height + 7)/8) *
|
||||
(png_ptr->bit_depth < 8 ? 12 : 6);
|
||||
int reduced = 0;
|
||||
png_alloc_size_t uncompressed_idat_size = png_image_size(png_ptr);
|
||||
|
||||
z_cinfo = z_cmf >> 4;
|
||||
half_z_window_size = 1 << (z_cinfo + 7);
|
||||
@@ -988,8 +996,12 @@ png_write_IDAT(png_structrp png_ptr, png_bytep data, png_size_t length)
|
||||
{
|
||||
z_cinfo--;
|
||||
half_z_window_size >>= 1;
|
||||
reduced = 1;
|
||||
}
|
||||
|
||||
if (reduced && !(png_ptr->flags & PNG_FLAG_ZSTREAM_CMF_FIXUP))
|
||||
png_warning(png_ptr, "internal data size error (IDAT)");
|
||||
|
||||
z_cmf = (z_cmf & 0x0f) | (z_cinfo << 4);
|
||||
|
||||
if (data[0] != z_cmf)
|
||||
|
||||
Reference in New Issue
Block a user