diff options
author | John Bowler <jbowler@acm.org> | 2013-01-19 23:18:59 -0600 |
---|---|---|
committer | Glenn Randers-Pehrson <glennrp at users.sourceforge.net> | 2013-01-19 23:18:59 -0600 |
commit | 2414bd99d8c76f92ca9272f1b1b1eff55709298a (patch) | |
tree | fb298f2d454e502fb24fbd11fadd9007f8ddf62f /pngmem.c | |
parent | 1f76e62d6cf80e5aa29b113a6e0fc1304e17826b (diff) | |
download | libpng-2414bd99d8c76f92ca9272f1b1b1eff55709298a.tar.gz |
[libpng16] Use consistent handling of overflows in text, sPLT and unknown
png_set_* APIs
Diffstat (limited to 'pngmem.c')
-rw-r--r-- | pngmem.c | 64 |
1 files changed, 63 insertions, 1 deletions
@@ -76,7 +76,7 @@ png_malloc_base,(png_const_structrp png_ptr, png_alloc_size_t size), #ifdef PNG_USER_MEM_SUPPORTED PNG_UNUSED(png_ptr) #endif - if (size > 0 && size <= ~(size_t)0 + if (size > 0 && size <= PNG_SIZE_MAX # ifdef PNG_MAX_MALLOC_64K && size <= 65536U # endif @@ -95,6 +95,68 @@ png_malloc_base,(png_const_structrp png_ptr, png_alloc_size_t size), return NULL; } +/* This is really here only to work round a spurious warning in GCC 4.6 and 4.7 + * that arises because of the checks in png_realloc_array that are repeated in + * png_malloc_array. + */ +static png_voidp +png_malloc_array_checked(png_const_structrp png_ptr, int nelements, + size_t element_size) +{ + png_alloc_size_t req = nelements; /* known to be > 0 */ + + if (req <= PNG_SIZE_MAX/element_size) + return png_malloc_base(png_ptr, req * element_size); + + /* The failure case when the request is too large */ + return NULL; +} + +PNG_FUNCTION(png_voidp /* PRIVATE */, +png_malloc_array,(png_const_structrp png_ptr, int nelements, + size_t element_size),PNG_ALLOCATED) +{ + if (nelements <= 0 || element_size == 0) + png_error(png_ptr, "internal error: array alloc"); + + return png_malloc_array_checked(png_ptr, nelements, element_size); +} + +PNG_FUNCTION(png_voidp /* PRIVATE */, +png_realloc_array,(png_const_structrp png_ptr, png_const_voidp old_array, + int old_elements, int add_elements, size_t element_size),PNG_ALLOCATED) +{ + /* These are internal errors: */ + if (add_elements <= 0 || element_size == 0 || old_elements < 0 || + (old_array == NULL && old_elements > 0)) + png_error(png_ptr, "internal error: array realloc"); + + /* Check for overflow on the elements count (so the caller does not have to + * check.) + */ + if (add_elements <= INT_MAX - old_elements) + { + png_voidp new_array = png_malloc_array_checked(png_ptr, + old_elements+add_elements, element_size); + + if (new_array != NULL) + { + /* Because png_malloc_array worked the size calculations below cannot + * overflow. + */ + if (old_elements > 0) + memcpy(new_array, old_array, element_size*(unsigned)old_elements); + + memset((char*)new_array + element_size*(unsigned)old_elements, 0, + element_size*(unsigned)add_elements); + + return new_array; + } + } + + return NULL; /* error */ +} + /* Various functions that have different error handling are derived from this. * png_malloc always exists, but if PNG_USER_MEM_SUPPORTED is defined a separate * function png_malloc_default is also provided. |