diff --git a/src/dec/frame_dec.c b/src/dec/frame_dec.c index 04609a8e..91ca1f86 100644 --- a/src/dec/frame_dec.c +++ b/src/dec/frame_dec.c @@ -705,7 +705,7 @@ static int AllocateMemory(VP8Decoder* const dec) { + cache_size + alpha_size + WEBP_ALIGN_CST; uint8_t* mem; - if (needed != (size_t)needed) return 0; // check for overflow + if (!CheckSizeOverflow(needed)) return 0; // check for overflow if (needed > dec->mem_size_) { WebPSafeFree(dec->mem_); dec->mem_size_ = 0; diff --git a/src/dec/io_dec.c b/src/dec/io_dec.c index 384cbced..8528c9d9 100644 --- a/src/dec/io_dec.c +++ b/src/dec/io_dec.c @@ -312,7 +312,7 @@ static int InitYUVRescaler(const VP8Io* const io, WebPDecParams* const p) { } rescaler_size = num_rescalers * sizeof(*p->scaler_y) + WEBP_ALIGN_CST; total_size += rescaler_size; - if (total_size != (size_t)total_size) { + if (!CheckSizeOverflow(total_size)) { return 0; } @@ -499,7 +499,7 @@ static int InitRGBRescaler(const VP8Io* const io, WebPDecParams* const p) { total_size = tmp_size1 * sizeof(*work) + tmp_size2 * sizeof(*tmp); rescaler_size = num_rescalers * sizeof(*p->scaler_y) + WEBP_ALIGN_CST; total_size += rescaler_size; - if (total_size != (size_t)total_size) { + if (!CheckSizeOverflow(total_size)) { return 0; } diff --git a/src/demux/anim_decode.c b/src/demux/anim_decode.c index b236ceb5..2bf4dcff 100644 --- a/src/demux/anim_decode.c +++ b/src/demux/anim_decode.c @@ -153,7 +153,7 @@ static int ZeroFillCanvas(uint8_t* buf, uint32_t canvas_width, uint32_t canvas_height) { const uint64_t size = (uint64_t)canvas_width * canvas_height * NUM_CHANNELS * sizeof(*buf); - if (size != (size_t)size) return 0; + if (!CheckSizeOverflow(size)) return 0; memset(buf, 0, (size_t)size); return 1; } @@ -174,7 +174,7 @@ static void ZeroFillFrameRect(uint8_t* buf, int buf_stride, int x_offset, static int CopyCanvas(const uint8_t* src, uint8_t* dst, uint32_t width, uint32_t height) { const uint64_t size = (uint64_t)width * height * NUM_CHANNELS; - if (size != (size_t)size) return 0; + if (!CheckSizeOverflow(size)) return 0; assert(src != NULL && dst != NULL); memcpy(dst, src, (size_t)size); return 1; diff --git a/src/utils/bit_writer_utils.c b/src/utils/bit_writer_utils.c index bef0e31c..2f408508 100644 --- a/src/utils/bit_writer_utils.c +++ b/src/utils/bit_writer_utils.c @@ -278,7 +278,7 @@ void VP8LPutBitsFlushBits(VP8LBitWriter* const bw) { // If needed, make some room by flushing some bits out. if (bw->cur_ + VP8L_WRITER_BYTES > bw->end_) { const uint64_t extra_size = (bw->end_ - bw->buf_) + MIN_EXTRA_SIZE; - if (extra_size != (size_t)extra_size || + if (!CheckSizeOverflow(extra_size) || !VP8LBitWriterResize(bw, (size_t)extra_size)) { bw->cur_ = bw->buf_; bw->error_ = 1; @@ -314,7 +314,7 @@ void VP8LPutBitsInternal(VP8LBitWriter* const bw, uint32_t bits, int n_bits) { while (used >= VP8L_WRITER_BITS) { if (bw->cur_ + VP8L_WRITER_BYTES > bw->end_) { const uint64_t extra_size = (bw->end_ - bw->buf_) + MIN_EXTRA_SIZE; - if (extra_size != (size_t)extra_size || + if (!CheckSizeOverflow(extra_size) || !VP8LBitWriterResize(bw, (size_t)extra_size)) { bw->cur_ = bw->buf_; bw->error_ = 1; diff --git a/src/utils/utils.c b/src/utils/utils.c index d021d840..9e464c16 100644 --- a/src/utils/utils.c +++ b/src/utils/utils.c @@ -172,7 +172,7 @@ 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; - if (total_size != (size_t)total_size) return 0; + if (!CheckSizeOverflow(total_size)) return 0; #if defined(PRINT_MEM_INFO) && defined(MALLOC_FAIL_AT) if (countdown_to_fail > 0 && --countdown_to_fail == 0) { return 0; // fake fail! @@ -181,7 +181,7 @@ static int CheckSizeArgumentsOverflow(uint64_t nmemb, size_t size) { #if defined(PRINT_MEM_INFO) && defined(MALLOC_LIMIT) if (mem_limit > 0) { const uint64_t new_total_mem = (uint64_t)total_mem + total_size; - if (new_total_mem != (size_t)new_total_mem || + if (!CheckSizeOverflow(new_total_mem) || new_total_mem > mem_limit) { return 0; // fake fail! } diff --git a/src/utils/utils.h b/src/utils/utils.h index adf16abd..ef04f108 100644 --- a/src/utils/utils.h +++ b/src/utils/utils.h @@ -42,6 +42,10 @@ extern "C" { #endif #endif // WEBP_MAX_ALLOCABLE_MEMORY +static WEBP_INLINE int CheckSizeOverflow(uint64_t size) { + return size == (size_t)size; +} + // size-checking safe malloc/calloc: verify that the requested size is not too // large, or return NULL. You don't need to call these for constructs like // malloc(sizeof(foo)), but only if there's picture-dependent size involved