Index: third_party/libwebp/demux/anim_decode.c |
diff --git a/third_party/libwebp/demux/anim_decode.c b/third_party/libwebp/demux/anim_decode.c |
index 1989eb4ab4c94ca99be8a6b7094b187895cac695..f1cf176e72d410664d8dc7578f19d449cc8ae704 100644 |
--- a/third_party/libwebp/demux/anim_decode.c |
+++ b/third_party/libwebp/demux/anim_decode.c |
@@ -112,18 +112,15 @@ WebPAnimDecoder* WebPAnimDecoderNewInternal( |
dec->info_.bgcolor = WebPDemuxGetI(dec->demux_, WEBP_FF_BACKGROUND_COLOR); |
dec->info_.frame_count = WebPDemuxGetI(dec->demux_, WEBP_FF_FRAME_COUNT); |
- { |
- const int canvas_bytes = |
- dec->info_.canvas_width * NUM_CHANNELS * dec->info_.canvas_height; |
- // Note: calloc() because we fill frame with zeroes as well. |
- dec->curr_frame_ = WebPSafeCalloc(1ULL, canvas_bytes); |
- if (dec->curr_frame_ == NULL) goto Error; |
- dec->prev_frame_disposed_ = WebPSafeCalloc(1ULL, canvas_bytes); |
- if (dec->prev_frame_disposed_ == NULL) goto Error; |
- } |
+ // Note: calloc() because we fill frame with zeroes as well. |
+ dec->curr_frame_ = (uint8_t*)WebPSafeCalloc( |
+ dec->info_.canvas_width * NUM_CHANNELS, dec->info_.canvas_height); |
+ if (dec->curr_frame_ == NULL) goto Error; |
+ dec->prev_frame_disposed_ = (uint8_t*)WebPSafeCalloc( |
+ dec->info_.canvas_width * NUM_CHANNELS, dec->info_.canvas_height); |
+ if (dec->prev_frame_disposed_ == NULL) goto Error; |
WebPAnimDecoderReset(dec); |
- |
return dec; |
Error: |
@@ -144,9 +141,13 @@ static int IsFullFrame(int width, int height, int canvas_width, |
} |
// Clear the canvas to transparent. |
-static void ZeroFillCanvas(uint8_t* buf, uint32_t canvas_width, |
- uint32_t canvas_height) { |
- memset(buf, 0, canvas_width * NUM_CHANNELS * canvas_height); |
+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; |
+ memset(buf, 0, (size_t)size); |
+ return 1; |
} |
// Clear given frame rectangle to transparent. |
@@ -162,10 +163,13 @@ static void ZeroFillFrameRect(uint8_t* buf, int buf_stride, int x_offset, |
} |
// Copy width * height pixels from 'src' to 'dst'. |
-static void CopyCanvas(const uint8_t* src, uint8_t* dst, |
- uint32_t width, uint32_t height) { |
+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; |
assert(src != NULL && dst != NULL); |
- memcpy(dst, src, width * NUM_CHANNELS * height); |
+ memcpy(dst, src, (size_t)size); |
+ return 1; |
} |
// Returns true if the current frame is a key-frame. |
@@ -328,9 +332,14 @@ int WebPAnimDecoderGetNext(WebPAnimDecoder* dec, |
is_key_frame = IsKeyFrame(&iter, &dec->prev_iter_, |
dec->prev_frame_was_keyframe_, width, height); |
if (is_key_frame) { |
- ZeroFillCanvas(dec->curr_frame_, width, height); |
+ if (!ZeroFillCanvas(dec->curr_frame_, width, height)) { |
+ goto Error; |
+ } |
} else { |
- CopyCanvas(dec->prev_frame_disposed_, dec->curr_frame_, width, height); |
+ if (!CopyCanvas(dec->prev_frame_disposed_, dec->curr_frame_, |
+ width, height)) { |
+ goto Error; |
+ } |
} |
// Decode. |
@@ -393,6 +402,7 @@ int WebPAnimDecoderGetNext(WebPAnimDecoder* dec, |
// Update info of the previous frame and dispose it for the next iteration. |
dec->prev_frame_timestamp_ = timestamp; |
+ WebPDemuxReleaseIterator(&dec->prev_iter_); |
dec->prev_iter_ = iter; |
dec->prev_frame_was_keyframe_ = is_key_frame; |
CopyCanvas(dec->curr_frame_, dec->prev_frame_disposed_, width, height); |
@@ -421,6 +431,7 @@ int WebPAnimDecoderHasMoreFrames(const WebPAnimDecoder* dec) { |
void WebPAnimDecoderReset(WebPAnimDecoder* dec) { |
if (dec != NULL) { |
dec->prev_frame_timestamp_ = 0; |
+ WebPDemuxReleaseIterator(&dec->prev_iter_); |
memset(&dec->prev_iter_, 0, sizeof(dec->prev_iter_)); |
dec->prev_frame_was_keyframe_ = 0; |
dec->next_frame_ = 1; |
@@ -434,6 +445,7 @@ const WebPDemuxer* WebPAnimDecoderGetDemuxer(const WebPAnimDecoder* dec) { |
void WebPAnimDecoderDelete(WebPAnimDecoder* dec) { |
if (dec != NULL) { |
+ WebPDemuxReleaseIterator(&dec->prev_iter_); |
WebPDemuxDelete(dec->demux_); |
WebPSafeFree(dec->curr_frame_); |
WebPSafeFree(dec->prev_frame_disposed_); |