From 9369eca108cc509ed651c0dbab6fa54de83727fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Klitzing?= Date: Tue, 3 Jan 2017 15:50:16 +0100 Subject: Update bundled libpng to version 1.6.28 Merged in the upstream version. The remaining diff to clean 1.6.28 is archived in the qtpatches.diff file. This fixes CVE-2016-10087 but Qt was never vulnerable to that issue! [ChangeLog][Third-Party Code] libpng was updated to version 1.6.28. Change-Id: I46712103fb160f31702eb7496fdd5c492a59ba5b Reviewed-by: Frederik Gladhorn Reviewed-by: Eirik Aavitsland --- src/3rdparty/libpng/pngset.c | 304 +++++++++++++++++++++++++++++-------------- 1 file changed, 204 insertions(+), 100 deletions(-) (limited to 'src/3rdparty/libpng/pngset.c') diff --git a/src/3rdparty/libpng/pngset.c b/src/3rdparty/libpng/pngset.c index 8fd7965fca..28ff3a064d 100644 --- a/src/3rdparty/libpng/pngset.c +++ b/src/3rdparty/libpng/pngset.c @@ -1,8 +1,8 @@ /* pngset.c - storage of image information into info struct * - * Last changed in libpng 1.6.19 [November 12, 2015] - * Copyright (c) 1998-2015 Glenn Randers-Pehrson + * Last changed in libpng 1.6.26 [October 20, 2016] + * Copyright (c) 1998-2016 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -104,14 +104,14 @@ png_set_cHRM(png_const_structrp png_ptr, png_inforp info_ptr, double green_x, double green_y, double blue_x, double blue_y) { png_set_cHRM_fixed(png_ptr, info_ptr, - png_fixed(png_ptr, white_x, "cHRM White X"), - png_fixed(png_ptr, white_y, "cHRM White Y"), - png_fixed(png_ptr, red_x, "cHRM Red X"), - png_fixed(png_ptr, red_y, "cHRM Red Y"), - png_fixed(png_ptr, green_x, "cHRM Green X"), - png_fixed(png_ptr, green_y, "cHRM Green Y"), - png_fixed(png_ptr, blue_x, "cHRM Blue X"), - png_fixed(png_ptr, blue_y, "cHRM Blue Y")); + png_fixed(png_ptr, white_x, "cHRM White X"), + png_fixed(png_ptr, white_y, "cHRM White Y"), + png_fixed(png_ptr, red_x, "cHRM Red X"), + png_fixed(png_ptr, red_y, "cHRM Red Y"), + png_fixed(png_ptr, green_x, "cHRM Green X"), + png_fixed(png_ptr, green_y, "cHRM Green Y"), + png_fixed(png_ptr, blue_x, "cHRM Blue X"), + png_fixed(png_ptr, blue_y, "cHRM Blue Y")); } void PNGAPI @@ -120,15 +120,15 @@ png_set_cHRM_XYZ(png_const_structrp png_ptr, png_inforp info_ptr, double red_X, double blue_X, double blue_Y, double blue_Z) { png_set_cHRM_XYZ_fixed(png_ptr, info_ptr, - png_fixed(png_ptr, red_X, "cHRM Red X"), - png_fixed(png_ptr, red_Y, "cHRM Red Y"), - png_fixed(png_ptr, red_Z, "cHRM Red Z"), - png_fixed(png_ptr, green_X, "cHRM Green X"), - png_fixed(png_ptr, green_Y, "cHRM Green Y"), - png_fixed(png_ptr, green_Z, "cHRM Green Z"), - png_fixed(png_ptr, blue_X, "cHRM Blue X"), - png_fixed(png_ptr, blue_Y, "cHRM Blue Y"), - png_fixed(png_ptr, blue_Z, "cHRM Blue Z")); + png_fixed(png_ptr, red_X, "cHRM Red X"), + png_fixed(png_ptr, red_Y, "cHRM Red Y"), + png_fixed(png_ptr, red_Z, "cHRM Red Z"), + png_fixed(png_ptr, green_X, "cHRM Green X"), + png_fixed(png_ptr, green_Y, "cHRM Green Y"), + png_fixed(png_ptr, green_Z, "cHRM Green Z"), + png_fixed(png_ptr, blue_X, "cHRM Blue X"), + png_fixed(png_ptr, blue_Y, "cHRM Blue Y"), + png_fixed(png_ptr, blue_Z, "cHRM Blue Z")); } # endif /* FLOATING_POINT */ @@ -283,17 +283,29 @@ png_set_pCAL(png_const_structrp png_ptr, png_inforp info_ptr, /* Check that the type matches the specification. */ if (type < 0 || type > 3) - png_error(png_ptr, "Invalid pCAL equation type"); + { + png_chunk_report(png_ptr, "Invalid pCAL equation type", + PNG_CHUNK_WRITE_ERROR); + return; + } if (nparams < 0 || nparams > 255) - png_error(png_ptr, "Invalid pCAL parameter count"); + { + png_chunk_report(png_ptr, "Invalid pCAL parameter count", + PNG_CHUNK_WRITE_ERROR); + return; + } /* Validate params[nparams] */ for (i=0; ipcal_purpose = png_voidcast(png_charp, @@ -301,8 +313,8 @@ png_set_pCAL(png_const_structrp png_ptr, png_inforp info_ptr, if (info_ptr->pcal_purpose == NULL) { - png_warning(png_ptr, "Insufficient memory for pCAL purpose"); - + png_chunk_report(png_ptr, "Insufficient memory for pCAL purpose", + PNG_CHUNK_WRITE_ERROR); return; } @@ -316,10 +328,10 @@ png_set_pCAL(png_const_structrp png_ptr, png_inforp info_ptr, length = strlen(units) + 1; png_debug1(3, "allocating units for info (%lu bytes)", - (unsigned long)length); + (unsigned long)length); info_ptr->pcal_units = png_voidcast(png_charp, - png_malloc_warn(png_ptr, length)); + png_malloc_warn(png_ptr, length)); if (info_ptr->pcal_units == NULL) { @@ -331,7 +343,7 @@ png_set_pCAL(png_const_structrp png_ptr, png_inforp info_ptr, memcpy(info_ptr->pcal_units, units, length); info_ptr->pcal_params = png_voidcast(png_charpp, png_malloc_warn(png_ptr, - (png_size_t)((nparams + 1) * (sizeof (png_charp))))); + (png_size_t)(((unsigned int)nparams + 1) * (sizeof (png_charp))))); if (info_ptr->pcal_params == NULL) { @@ -340,7 +352,8 @@ png_set_pCAL(png_const_structrp png_ptr, png_inforp info_ptr, return; } - memset(info_ptr->pcal_params, 0, (nparams + 1) * (sizeof (png_charp))); + memset(info_ptr->pcal_params, 0, ((unsigned int)nparams + 1) * + (sizeof (png_charp))); for (i = 0; i < nparams; i++) { @@ -398,7 +411,7 @@ png_set_sCAL_s(png_const_structrp png_ptr, png_inforp info_ptr, png_debug1(3, "allocating unit for info (%u bytes)", (unsigned int)lengthw); info_ptr->scal_s_width = png_voidcast(png_charp, - png_malloc_warn(png_ptr, lengthw)); + png_malloc_warn(png_ptr, lengthw)); if (info_ptr->scal_s_width == NULL) { @@ -414,7 +427,7 @@ png_set_sCAL_s(png_const_structrp png_ptr, png_inforp info_ptr, png_debug1(3, "allocating unit for info (%u bytes)", (unsigned int)lengthh); info_ptr->scal_s_height = png_voidcast(png_charp, - png_malloc_warn(png_ptr, lengthh)); + png_malloc_warn(png_ptr, lengthh)); if (info_ptr->scal_s_height == NULL) { @@ -453,9 +466,9 @@ png_set_sCAL(png_const_structrp png_ptr, png_inforp info_ptr, int unit, char sheight[PNG_sCAL_MAX_DIGITS+1]; png_ascii_from_fp(png_ptr, swidth, (sizeof swidth), width, - PNG_sCAL_PRECISION); + PNG_sCAL_PRECISION); png_ascii_from_fp(png_ptr, sheight, (sizeof sheight), height, - PNG_sCAL_PRECISION); + PNG_sCAL_PRECISION); png_set_sCAL_s(png_ptr, info_ptr, unit, swidth, sheight); } @@ -563,7 +576,8 @@ png_set_PLTE(png_structrp png_ptr, png_inforp info_ptr, PNG_MAX_PALETTE_LENGTH * (sizeof (png_color)))); if (num_palette > 0) - memcpy(png_ptr->palette, palette, num_palette * (sizeof (png_color))); + memcpy(png_ptr->palette, palette, (unsigned int)num_palette * + (sizeof (png_color))); info_ptr->palette = png_ptr->palette; info_ptr->num_palette = png_ptr->num_palette = (png_uint_16)num_palette; @@ -648,7 +662,7 @@ png_set_iCCP(png_const_structrp png_ptr, png_inforp info_ptr, */ { int result = png_colorspace_set_ICC(png_ptr, &info_ptr->colorspace, name, - proflen, profile, info_ptr->color_type); + proflen, profile, info_ptr->color_type); png_colorspace_sync_info(png_ptr, info_ptr); @@ -673,7 +687,7 @@ png_set_iCCP(png_const_structrp png_ptr, png_inforp info_ptr, memcpy(new_iccp_name, name, length); new_iccp_profile = png_voidcast(png_bytep, - png_malloc_warn(png_ptr, proflen)); + png_malloc_warn(png_ptr, proflen)); if (new_iccp_profile == NULL) { @@ -748,14 +762,14 @@ png_set_text_2(png_const_structrp png_ptr, png_inforp info_ptr, * the overflow checks. */ new_text = png_voidcast(png_textp,png_realloc_array(png_ptr, - info_ptr->text, old_num_text, max_text-old_num_text, - sizeof *new_text)); + info_ptr->text, old_num_text, max_text-old_num_text, + sizeof *new_text)); } if (new_text == NULL) { png_chunk_report(png_ptr, "too many text chunks", - PNG_CHUNK_WRITE_ERROR); + PNG_CHUNK_WRITE_ERROR); return 1; } @@ -783,7 +797,7 @@ png_set_text_2(png_const_structrp png_ptr, png_inforp info_ptr, text_ptr[i].compression >= PNG_TEXT_COMPRESSION_LAST) { png_chunk_report(png_ptr, "text compression mode is out of range", - PNG_CHUNK_WRITE_ERROR); + PNG_CHUNK_WRITE_ERROR); continue; } @@ -815,7 +829,7 @@ png_set_text_2(png_const_structrp png_ptr, png_inforp info_ptr, # else /* iTXt */ { png_chunk_report(png_ptr, "iTXt chunk not supported", - PNG_CHUNK_WRITE_ERROR); + PNG_CHUNK_WRITE_ERROR); continue; } # endif @@ -844,7 +858,7 @@ png_set_text_2(png_const_structrp png_ptr, png_inforp info_ptr, if (textp->key == NULL) { png_chunk_report(png_ptr, "text chunk: out of memory", - PNG_CHUNK_WRITE_ERROR); + PNG_CHUNK_WRITE_ERROR); return 1; } @@ -952,12 +966,14 @@ png_set_tRNS(png_structrp png_ptr, png_inforp info_ptr, png_free_data(png_ptr, info_ptr, PNG_FREE_TRNS, 0); - /* Changed from num_trans to PNG_MAX_PALETTE_LENGTH in version 1.2.1 */ - png_ptr->trans_alpha = info_ptr->trans_alpha = png_voidcast(png_bytep, - png_malloc(png_ptr, PNG_MAX_PALETTE_LENGTH)); - if (num_trans > 0 && num_trans <= PNG_MAX_PALETTE_LENGTH) + { + /* Changed from num_trans to PNG_MAX_PALETTE_LENGTH in version 1.2.1 */ + info_ptr->trans_alpha = png_voidcast(png_bytep, + png_malloc(png_ptr, PNG_MAX_PALETTE_LENGTH)); memcpy(info_ptr->trans_alpha, trans_alpha, (png_size_t)num_trans); + } + png_ptr->trans_alpha = info_ptr->trans_alpha; } if (trans_color != NULL) @@ -974,7 +990,7 @@ png_set_tRNS(png_structrp png_ptr, png_inforp info_ptr, trans_color->green > sample_max || trans_color->blue > sample_max))) png_warning(png_ptr, - "tRNS chunk has out-of-range samples for bit_depth"); + "tRNS chunk has out-of-range samples for bit_depth"); } #endif @@ -1016,8 +1032,8 @@ png_set_sPLT(png_const_structrp png_ptr, * overflows. Notice that the parameters are (int) and (size_t) */ np = png_voidcast(png_sPLT_tp,png_realloc_array(png_ptr, - info_ptr->splt_palettes, info_ptr->splt_palettes_num, nentries, - sizeof *np)); + info_ptr->splt_palettes, info_ptr->splt_palettes_num, nentries, + sizeof *np)); if (np == NULL) { @@ -1078,7 +1094,7 @@ png_set_sPLT(png_const_structrp png_ptr, * checked it when doing the allocation. */ memcpy(np->entries, entries->entries, - entries->nentries * sizeof (png_sPLT_entry)); + (unsigned int)entries->nentries * sizeof (png_sPLT_entry)); /* Note that 'continue' skips the advance of the out pointer and out * count, so an invalid entry is not added. @@ -1108,10 +1124,10 @@ check_location(png_const_structrp png_ptr, int location) { /* Write struct, so unknown chunks come from the app */ png_app_warning(png_ptr, - "png_set_unknown_chunks now expects a valid location"); + "png_set_unknown_chunks now expects a valid location"); /* Use the old behavior */ location = (png_byte)(png_ptr->mode & - (PNG_HAVE_IHDR|PNG_HAVE_PLTE|PNG_AFTER_IDAT)); + (PNG_HAVE_IHDR|PNG_HAVE_PLTE|PNG_AFTER_IDAT)); } /* This need not be an internal error - if the app calls @@ -1134,7 +1150,7 @@ check_location(png_const_structrp png_ptr, int location) void PNGAPI png_set_unknown_chunks(png_const_structrp png_ptr, - png_inforp info_ptr, png_const_unknown_chunkp unknowns, int num_unknowns) + png_inforp info_ptr, png_const_unknown_chunkp unknowns, int num_unknowns) { png_unknown_chunkp np; @@ -1173,13 +1189,13 @@ png_set_unknown_chunks(png_const_structrp png_ptr, * appropriate to read or write. */ np = png_voidcast(png_unknown_chunkp, png_realloc_array(png_ptr, - info_ptr->unknown_chunks, info_ptr->unknown_chunks_num, num_unknowns, - sizeof *np)); + info_ptr->unknown_chunks, info_ptr->unknown_chunks_num, num_unknowns, + sizeof *np)); if (np == NULL) { png_chunk_report(png_ptr, "too many unknown chunks", - PNG_CHUNK_WRITE_ERROR); + PNG_CHUNK_WRITE_ERROR); return; } @@ -1208,12 +1224,12 @@ png_set_unknown_chunks(png_const_structrp png_ptr, else { np->data = png_voidcast(png_bytep, - png_malloc_base(png_ptr, unknowns->size)); + png_malloc_base(png_ptr, unknowns->size)); if (np->data == NULL) { png_chunk_report(png_ptr, "unknown chunk: out of memory", - PNG_CHUNK_WRITE_ERROR); + PNG_CHUNK_WRITE_ERROR); /* But just skip storing the unknown chunk */ continue; } @@ -1247,7 +1263,7 @@ png_set_unknown_chunk_location(png_const_structrp png_ptr, png_inforp info_ptr, { png_app_error(png_ptr, "invalid unknown chunk location"); /* Fake out the pre 1.6.0 behavior: */ - if ((location & PNG_HAVE_IDAT) != 0) /* undocumented! */ + if (((unsigned int)location & PNG_HAVE_IDAT) != 0) /* undocumented! */ location = PNG_AFTER_IDAT; else @@ -1371,7 +1387,7 @@ png_set_keep_unknown_chunks(png_structrp png_ptr, int keep, return; } - num_chunks = num_chunks_in; + num_chunks = (unsigned int)num_chunks_in; } old_num_chunks = png_ptr->num_chunk_list; @@ -1420,7 +1436,7 @@ png_set_keep_unknown_chunks(png_structrp png_ptr, int keep, for (i=0; i PNG_UINT_31_MAX) - png_error(png_ptr, "invalid compression buffer size"); + if (size == 0 || size > PNG_UINT_31_MAX) + png_error(png_ptr, "invalid compression buffer size"); # ifdef PNG_SEQUENTIAL_READ_SUPPORTED - if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0) - { - png_ptr->IDAT_read_size = (png_uint_32)size; /* checked above */ - return; - } + if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0) + { + png_ptr->IDAT_read_size = (png_uint_32)size; /* checked above */ + return; + } # endif # ifdef PNG_WRITE_SUPPORTED - if ((png_ptr->mode & PNG_IS_READ_STRUCT) == 0) + if ((png_ptr->mode & PNG_IS_READ_STRUCT) == 0) + { + if (png_ptr->zowner != 0) { - if (png_ptr->zowner != 0) - { - png_warning(png_ptr, - "Compression buffer size cannot be changed because it is in use"); + png_warning(png_ptr, + "Compression buffer size cannot be changed because it is in use"); - return; - } + return; + } #ifndef __COVERITY__ - /* Some compilers complain that this is always false. However, it - * can be true when integer overflow happens. - */ - if (size > ZLIB_IO_MAX) - { - png_warning(png_ptr, - "Compression buffer size limited to system maximum"); - size = ZLIB_IO_MAX; /* must fit */ - } + /* Some compilers complain that this is always false. However, it + * can be true when integer overflow happens. + */ + if (size > ZLIB_IO_MAX) + { + png_warning(png_ptr, + "Compression buffer size limited to system maximum"); + size = ZLIB_IO_MAX; /* must fit */ + } #endif - if (size < 6) - { - /* Deflate will potentially go into an infinite loop on a SYNC_FLUSH - * if this is permitted. - */ - png_warning(png_ptr, - "Compression buffer size cannot be reduced below 6"); + if (size < 6) + { + /* Deflate will potentially go into an infinite loop on a SYNC_FLUSH + * if this is permitted. + */ + png_warning(png_ptr, + "Compression buffer size cannot be reduced below 6"); - return; - } + return; + } - if (png_ptr->zbuffer_size != size) - { - png_free_buffer_list(png_ptr, &png_ptr->zbuffer_list); - png_ptr->zbuffer_size = (uInt)size; - } + if (png_ptr->zbuffer_size != size) + { + png_free_buffer_list(png_ptr, &png_ptr->zbuffer_list); + png_ptr->zbuffer_size = (uInt)size; } + } # endif } @@ -1561,7 +1577,7 @@ void PNGAPI png_set_invalid(png_const_structrp png_ptr, png_inforp info_ptr, int mask) { if (png_ptr != NULL && info_ptr != NULL) - info_ptr->valid &= ~mask; + info_ptr->valid &= (unsigned int)(~mask); } @@ -1644,4 +1660,92 @@ png_set_check_for_invalid_index(png_structrp png_ptr, int allowed) png_ptr->num_palette_max = -1; } #endif + +#if defined(PNG_TEXT_SUPPORTED) || defined(PNG_pCAL_SUPPORTED) || \ + defined(PNG_iCCP_SUPPORTED) || defined(PNG_sPLT_SUPPORTED) +/* Check that the tEXt or zTXt keyword is valid per PNG 1.0 specification, + * and if invalid, correct the keyword rather than discarding the entire + * chunk. The PNG 1.0 specification requires keywords 1-79 characters in + * length, forbids leading or trailing whitespace, multiple internal spaces, + * and the non-break space (0x80) from ISO 8859-1. Returns keyword length. + * + * The 'new_key' buffer must be 80 characters in size (for the keyword plus a + * trailing '\0'). If this routine returns 0 then there was no keyword, or a + * valid one could not be generated, and the caller must png_error. + */ +png_uint_32 /* PRIVATE */ +png_check_keyword(png_structrp png_ptr, png_const_charp key, png_bytep new_key) +{ +#ifdef PNG_WARNINGS_SUPPORTED + png_const_charp orig_key = key; +#endif + png_uint_32 key_len = 0; + int bad_character = 0; + int space = 1; + + png_debug(1, "in png_check_keyword"); + + if (key == NULL) + { + *new_key = 0; + return 0; + } + + while (*key && key_len < 79) + { + png_byte ch = (png_byte)*key++; + + if ((ch > 32 && ch <= 126) || (ch >= 161 /*&& ch <= 255*/)) + *new_key++ = ch, ++key_len, space = 0; + + else if (space == 0) + { + /* A space or an invalid character when one wasn't seen immediately + * before; output just a space. + */ + *new_key++ = 32, ++key_len, space = 1; + + /* If the character was not a space then it is invalid. */ + if (ch != 32) + bad_character = ch; + } + + else if (bad_character == 0) + bad_character = ch; /* just skip it, record the first error */ + } + + if (key_len > 0 && space != 0) /* trailing space */ + { + --key_len, --new_key; + if (bad_character == 0) + bad_character = 32; + } + + /* Terminate the keyword */ + *new_key = 0; + + if (key_len == 0) + return 0; + +#ifdef PNG_WARNINGS_SUPPORTED + /* Try to only output one warning per keyword: */ + if (*key != 0) /* keyword too long */ + png_warning(png_ptr, "keyword truncated"); + + else if (bad_character != 0) + { + PNG_WARNING_PARAMETERS(p) + + png_warning_parameter(p, 1, orig_key); + png_warning_parameter_signed(p, 2, PNG_NUMBER_FORMAT_02x, bad_character); + + png_formatted_warning(png_ptr, p, "keyword \"@1\": bad character '0x@2'"); + } +#else /* !WARNINGS */ + PNG_UNUSED(png_ptr) +#endif /* !WARNINGS */ + + return key_len; +} +#endif /* TEXT || pCAL || iCCP || sPLT */ #endif /* READ || WRITE */ -- cgit v1.2.3