| diff --git a/png.c b/png.c |
| index 35e14f63d..01d8d9bae 100644 |
| --- a/png.c |
| +++ b/png.c |
| @@ -1931,8 +1931,8 @@ png_colorspace_set_sRGB(png_const_structrp png_ptr, png_colorspacerp colorspace, |
| static const png_byte D50_nCIEXYZ[12] = |
| { 0x00, 0x00, 0xf6, 0xd6, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x2d }; |
| |
| -int /* PRIVATE */ |
| -png_icc_check_length(png_const_structrp png_ptr, png_colorspacerp colorspace, |
| +static int /* bool */ |
| +icc_check_length(png_const_structrp png_ptr, png_colorspacerp colorspace, |
| png_const_charp name, png_uint_32 profile_length) |
| { |
| if (profile_length < 132) |
| @@ -1942,6 +1942,40 @@ png_icc_check_length(png_const_structrp png_ptr, png_colorspacerp colorspace, |
| return 1; |
| } |
| |
| +#ifdef PNG_READ_iCCP_SUPPORTED |
| +int /* PRIVATE */ |
| +png_icc_check_length(png_const_structrp png_ptr, png_colorspacerp colorspace, |
| + png_const_charp name, png_uint_32 profile_length) |
| +{ |
| + if (!icc_check_length(png_ptr, colorspace, name, profile_length)) |
| + return 0; |
| + |
| + /* This needs to be here because the 'normal' check is in |
| + * png_decompress_chunk, yet this happens after the attempt to |
| + * png_malloc_base the required data. We only need this on read; on write |
| + * the caller supplies the profile buffer so libpng doesn't allocate it. See |
| + * the call to icc_check_length below (the write case). |
| + */ |
| +# ifdef PNG_SET_USER_LIMITS_SUPPORTED |
| + else if (png_ptr->user_chunk_malloc_max > 0 && |
| + png_ptr->user_chunk_malloc_max < profile_length) |
| + return png_icc_profile_error(png_ptr, colorspace, name, profile_length, |
| + "exceeds application limits"); |
| +# elif PNG_USER_CHUNK_MALLOC_MAX > 0 |
| + else if (PNG_USER_CHUNK_MALLOC_MAX < profile_length) |
| + return png_icc_profile_error(png_ptr, colorspace, name, profile_length, |
| + "exceeds libpng limits"); |
| +# else /* !SET_USER_LIMITS */ |
| + /* This will get compiled out on all 32-bit and better systems. */ |
| + else if (PNG_SIZE_MAX < profile_length) |
| + return png_icc_profile_error(png_ptr, colorspace, name, profile_length, |
| + "exceeds system limits"); |
| +# endif /* !SET_USER_LIMITS */ |
| + |
| + return 1; |
| +} |
| +#endif /* READ_iCCP */ |
| + |
| int /* PRIVATE */ |
| png_icc_check_header(png_const_structrp png_ptr, png_colorspacerp colorspace, |
| png_const_charp name, png_uint_32 profile_length, |
| @@ -2379,7 +2413,7 @@ png_colorspace_set_ICC(png_const_structrp png_ptr, png_colorspacerp colorspace, |
| if ((colorspace->flags & PNG_COLORSPACE_INVALID) != 0) |
| return 0; |
| |
| - if (png_icc_check_length(png_ptr, colorspace, name, profile_length) != 0 && |
| + if (icc_check_length(png_ptr, colorspace, name, profile_length) != 0 && |
| png_icc_check_header(png_ptr, colorspace, name, profile_length, profile, |
| color_type) != 0 && |
| png_icc_check_tag_table(png_ptr, colorspace, name, profile_length, |
| diff --git a/pngpriv.h b/pngpriv.h |
| index 9ea023fea..633671352 100644 |
| --- a/pngpriv.h |
| +++ b/pngpriv.h |
| @@ -1541,9 +1541,11 @@ PNG_INTERNAL_FUNCTION(int,png_colorspace_set_ICC,(png_const_structrp png_ptr, |
| /* The 'name' is used for information only */ |
| |
| /* Routines for checking parts of an ICC profile. */ |
| +#ifdef PNG_READ_iCCP_SUPPORTED |
| PNG_INTERNAL_FUNCTION(int,png_icc_check_length,(png_const_structrp png_ptr, |
| png_colorspacerp colorspace, png_const_charp name, |
| png_uint_32 profile_length), PNG_EMPTY); |
| +#endif /* READ_iCCP */ |
| PNG_INTERNAL_FUNCTION(int,png_icc_check_header,(png_const_structrp png_ptr, |
| png_colorspacerp colorspace, png_const_charp name, |
| png_uint_32 profile_length, |