Fix potential overflow in FramesAreSimilar

Bug: 496807858

Change-Id: Idc9af6f86a171322dd09e197dafbef59d5e4aa53
This commit is contained in:
Vincent Rabaud
2026-04-07 09:42:11 +02:00
parent 7ab12ced1e
commit 6a9eb44282
3 changed files with 10 additions and 5 deletions

View File

@@ -70,8 +70,10 @@ static int FramesAreSimilar(const uint8_t* const rgba1,
for (j = 0; j < height; ++j) { for (j = 0; j < height; ++j) {
for (i = 0; i < width; ++i) { for (i = 0; i < width; ++i) {
const int stride = width * 4; const int stride = width * 4;
const size_t offset = j * stride + i; size_t offset_row, offset;
if (!PixelsAreSimilar(rgba1[offset], rgba2[offset], max_allowed_diff)) { if (!CheckMultiplicationOverflow(j, stride, &offset_row) ||
!CheckAdditionOverflow(offset_row, i, &offset) ||
!PixelsAreSimilar(rgba1[offset], rgba2[offset], max_allowed_diff)) {
return 0; return 0;
} }
} }

View File

@@ -102,10 +102,8 @@ int CheckMultiplicationOverflow(uint32_t val1, uint32_t val2, size_t* product) {
return 0; return 0;
} }
#if defined(WEBP_HAVE_GIF)
WEBP_NODISCARD WEBP_NODISCARD
static int CheckAdditionOverflow(size_t val1, uint32_t val2, size_t* addition) { int CheckAdditionOverflow(size_t val1, uint32_t val2, size_t* addition) {
const uint64_t size = (uint64_t)val1 + val2; const uint64_t size = (uint64_t)val1 + val2;
if (CheckSizeForOverflow(size)) { if (CheckSizeForOverflow(size)) {
*addition = (size_t)size; *addition = (size_t)size;
@@ -114,6 +112,8 @@ static int CheckAdditionOverflow(size_t val1, uint32_t val2, size_t* addition) {
return 0; return 0;
} }
#if defined(WEBP_HAVE_GIF)
// For the GIF functions below, the width, height, x_offset, y_offset fit on 16 // For the GIF functions below, the width, height, x_offset, y_offset fit on 16
// bits (but can fill the 16 bits) as per the GIF specification. // bits (but can fill the 16 bits) as per the GIF specification.
// Multiplications that can overflow are cast to 64 bits. // Multiplications that can overflow are cast to 64 bits.

View File

@@ -73,6 +73,9 @@ void GetAnimatedImageVersions(int* const decoder_version,
// Check whether val1 * val2 fits in a size_t. Returns 1 on success. // Check whether val1 * val2 fits in a size_t. Returns 1 on success.
int CheckMultiplicationOverflow(uint32_t val1, uint32_t val2, size_t* product); int CheckMultiplicationOverflow(uint32_t val1, uint32_t val2, size_t* product);
// Check whether val1 + val2 fits in a size_t. Returns 1 on success.
int CheckAdditionOverflow(size_t val1, uint32_t val2, size_t* addition);
#ifdef __cplusplus #ifdef __cplusplus
} // extern "C" } // extern "C"
#endif #endif