mirror of
https://github.com/webmproject/libwebp.git
synced 2024-12-27 22:28:22 +01:00
utils.h: add SizeOverflow()
this normalizes the 'size != (size_t)size' checks in the libraries. Change-Id: I1e8ccd0d3697266f23911ecf0f7a546f011befde
This commit is contained in:
parent
695bdaa2f6
commit
28d488e6f1
@ -705,7 +705,7 @@ static int AllocateMemory(VP8Decoder* const dec) {
|
|||||||
+ cache_size + alpha_size + WEBP_ALIGN_CST;
|
+ cache_size + alpha_size + WEBP_ALIGN_CST;
|
||||||
uint8_t* mem;
|
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_) {
|
if (needed > dec->mem_size_) {
|
||||||
WebPSafeFree(dec->mem_);
|
WebPSafeFree(dec->mem_);
|
||||||
dec->mem_size_ = 0;
|
dec->mem_size_ = 0;
|
||||||
|
@ -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;
|
rescaler_size = num_rescalers * sizeof(*p->scaler_y) + WEBP_ALIGN_CST;
|
||||||
total_size += rescaler_size;
|
total_size += rescaler_size;
|
||||||
if (total_size != (size_t)total_size) {
|
if (!CheckSizeOverflow(total_size)) {
|
||||||
return 0;
|
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);
|
total_size = tmp_size1 * sizeof(*work) + tmp_size2 * sizeof(*tmp);
|
||||||
rescaler_size = num_rescalers * sizeof(*p->scaler_y) + WEBP_ALIGN_CST;
|
rescaler_size = num_rescalers * sizeof(*p->scaler_y) + WEBP_ALIGN_CST;
|
||||||
total_size += rescaler_size;
|
total_size += rescaler_size;
|
||||||
if (total_size != (size_t)total_size) {
|
if (!CheckSizeOverflow(total_size)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,7 +153,7 @@ static int ZeroFillCanvas(uint8_t* buf, uint32_t canvas_width,
|
|||||||
uint32_t canvas_height) {
|
uint32_t canvas_height) {
|
||||||
const uint64_t size =
|
const uint64_t size =
|
||||||
(uint64_t)canvas_width * canvas_height * NUM_CHANNELS * sizeof(*buf);
|
(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);
|
memset(buf, 0, (size_t)size);
|
||||||
return 1;
|
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,
|
static int CopyCanvas(const uint8_t* src, uint8_t* dst,
|
||||||
uint32_t width, uint32_t height) {
|
uint32_t width, uint32_t height) {
|
||||||
const uint64_t size = (uint64_t)width * height * NUM_CHANNELS;
|
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);
|
assert(src != NULL && dst != NULL);
|
||||||
memcpy(dst, src, (size_t)size);
|
memcpy(dst, src, (size_t)size);
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -278,7 +278,7 @@ void VP8LPutBitsFlushBits(VP8LBitWriter* const bw) {
|
|||||||
// If needed, make some room by flushing some bits out.
|
// If needed, make some room by flushing some bits out.
|
||||||
if (bw->cur_ + VP8L_WRITER_BYTES > bw->end_) {
|
if (bw->cur_ + VP8L_WRITER_BYTES > bw->end_) {
|
||||||
const uint64_t extra_size = (bw->end_ - bw->buf_) + MIN_EXTRA_SIZE;
|
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)) {
|
!VP8LBitWriterResize(bw, (size_t)extra_size)) {
|
||||||
bw->cur_ = bw->buf_;
|
bw->cur_ = bw->buf_;
|
||||||
bw->error_ = 1;
|
bw->error_ = 1;
|
||||||
@ -314,7 +314,7 @@ void VP8LPutBitsInternal(VP8LBitWriter* const bw, uint32_t bits, int n_bits) {
|
|||||||
while (used >= VP8L_WRITER_BITS) {
|
while (used >= VP8L_WRITER_BITS) {
|
||||||
if (bw->cur_ + VP8L_WRITER_BYTES > bw->end_) {
|
if (bw->cur_ + VP8L_WRITER_BYTES > bw->end_) {
|
||||||
const uint64_t extra_size = (bw->end_ - bw->buf_) + MIN_EXTRA_SIZE;
|
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)) {
|
!VP8LBitWriterResize(bw, (size_t)extra_size)) {
|
||||||
bw->cur_ = bw->buf_;
|
bw->cur_ = bw->buf_;
|
||||||
bw->error_ = 1;
|
bw->error_ = 1;
|
||||||
|
@ -172,7 +172,7 @@ static int CheckSizeArgumentsOverflow(uint64_t nmemb, size_t size) {
|
|||||||
const uint64_t total_size = nmemb * size;
|
const uint64_t total_size = nmemb * size;
|
||||||
if (nmemb == 0) return 1;
|
if (nmemb == 0) return 1;
|
||||||
if ((uint64_t)size > WEBP_MAX_ALLOCABLE_MEMORY / nmemb) return 0;
|
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 defined(PRINT_MEM_INFO) && defined(MALLOC_FAIL_AT)
|
||||||
if (countdown_to_fail > 0 && --countdown_to_fail == 0) {
|
if (countdown_to_fail > 0 && --countdown_to_fail == 0) {
|
||||||
return 0; // fake fail!
|
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 defined(PRINT_MEM_INFO) && defined(MALLOC_LIMIT)
|
||||||
if (mem_limit > 0) {
|
if (mem_limit > 0) {
|
||||||
const uint64_t new_total_mem = (uint64_t)total_mem + total_size;
|
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) {
|
new_total_mem > mem_limit) {
|
||||||
return 0; // fake fail!
|
return 0; // fake fail!
|
||||||
}
|
}
|
||||||
|
@ -42,6 +42,10 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
#endif // WEBP_MAX_ALLOCABLE_MEMORY
|
#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
|
// 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
|
// 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
|
// malloc(sizeof(foo)), but only if there's picture-dependent size involved
|
||||||
|
Loading…
Reference in New Issue
Block a user