From 42f8f9346ce9752d02a99a9ce545866da672ecaf Mon Sep 17 00:00:00 2001 From: skal Date: Tue, 22 Jan 2013 10:34:35 +0100 Subject: [PATCH] handle malloc(0) and calloc(0) uniformly on all platforms also change lossless encoder logic, which was relying on explicit NULL return from WebPSafeMalloc(0) renamed function to CheckSizeArgumentsOverflow() explicitly addresses issue #138 Change-Id: Ibbd51cc0281e60e86dfd4c5496274399e4c0f7f3 --- src/enc/vp8l.c | 8 ++++++-- src/utils/huffman_encode.c | 4 ++++ src/utils/utils.c | 11 ++++++----- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/enc/vp8l.c b/src/enc/vp8l.c index bd73e56a..56131b9c 100644 --- a/src/enc/vp8l.c +++ b/src/enc/vp8l.c @@ -221,7 +221,7 @@ static int GetHuffBitLengthsAndCodes( } // Create Huffman trees. - for (i = 0; i < histogram_image_size; ++i) { + for (i = 0; ok && (i < histogram_image_size); ++i) { HuffmanTreeCode* const codes = &huffman_codes[5 * i]; VP8LHistogram* const histo = histogram_image->histograms[i]; ok = ok && VP8LCreateHuffmanTree(histo->literal_, 15, codes + 0); @@ -232,7 +232,11 @@ static int GetHuffBitLengthsAndCodes( } End: - if (!ok) free(mem_buf); + if (!ok) { + free(mem_buf); + // If one VP8LCreateHuffmanTree() above fails, we need to clean up behind. + memset(huffman_codes, 0, 5 * histogram_image_size * sizeof(*huffman_codes)); + } return ok; } diff --git a/src/utils/huffman_encode.c b/src/utils/huffman_encode.c index e8cbc628..2d680e3e 100644 --- a/src/utils/huffman_encode.c +++ b/src/utils/huffman_encode.c @@ -188,6 +188,10 @@ static int GenerateOptimalTree(const int* const histogram, int histogram_size, } } + if (tree_size_orig == 0) { // pretty optimal already! + return 1; + } + // 3 * tree_size is enough to cover all the nodes representing a // population and all the inserted nodes combining two existing nodes. // The tree pool needs 2 * (tree_size_orig - 1) entities, and the diff --git a/src/utils/utils.c b/src/utils/utils.c index 673b7e28..555f9a33 100644 --- a/src/utils/utils.c +++ b/src/utils/utils.c @@ -19,7 +19,8 @@ extern "C" { //------------------------------------------------------------------------------ // Checked memory allocation -static int CheckSizeArguments(uint64_t nmemb, size_t size) { +// Returns 0 in case of overflow of nmemb * size. +static int CheckSizeArgumentsOverflow(uint64_t nmemb, size_t size) { const uint64_t total_size = nmemb * size; if (nmemb == 0) return 1; if ((uint64_t)size > WEBP_MAX_ALLOCABLE_MEMORY / nmemb) return 0; @@ -28,13 +29,13 @@ static int CheckSizeArguments(uint64_t nmemb, size_t size) { } void* WebPSafeMalloc(uint64_t nmemb, size_t size) { - if (!CheckSizeArguments(nmemb, size)) return NULL; - return malloc((size_t)(nmemb * size)); + if (!CheckSizeArgumentsOverflow(nmemb, size)) return NULL; + return (nmemb > 0 && size > 0) ? malloc((size_t)(nmemb * size)) : NULL; } void* WebPSafeCalloc(uint64_t nmemb, size_t size) { - if (!CheckSizeArguments(nmemb, size)) return NULL; - return calloc((size_t)nmemb, size); + if (!CheckSizeArgumentsOverflow(nmemb, size)) return NULL; + return (nmemb > 0 && size > 0) ? calloc((size_t)nmemb, size) : NULL; } //------------------------------------------------------------------------------