Fix int overflow in ARGBRotate pointer math

ARGBRotate90, ARGBRotate180 and ARGBRotate270 adjusted the source and
destination base pointers with expressions like src_stride_argb *
(height - 1) and dst_stride_argb * (width - 1) using 32-bit int
multiplication. For large frames this product overflows int before it
is applied as a pointer offset, yielding an out-of-bounds pointer even
on 64-bit targets (in the 90/270 cases the bad base pointer is then
passed to ARGBTranspose).

Cast the stride to ptrdiff_t before multiplying so the arithmetic is
performed in pointer width, matching the existing correct pattern at
rotate.cc:164 and rotate_argb.cc:235.

R=fbarchard@google.com

Change-Id: Ia4fd5d813de4fb7fa72c46aee723eca65980bccc
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8070980
Reviewed-by: Frank Barchard <fbarchard@google.com>
Reviewed-by: Wan-Teh Chang <wtc@google.com>
Commit-Queue: Max Hils <mhils@google.com>
This commit is contained in:
Maximilian Hils 2026-07-10 14:11:43 +00:00 committed by libyuv-scoped@luci-project-accounts.iam.gserviceaccount.com
parent afff0cf68b
commit 45258a40a0

View File

@ -86,7 +86,7 @@ static int ARGBRotate90(const uint8_t* src_argb,
// Rotate by 90 is a ARGBTranspose with the source read // Rotate by 90 is a ARGBTranspose with the source read
// from bottom to top. So set the source pointer to the end // from bottom to top. So set the source pointer to the end
// of the buffer and flip the sign of the source stride. // of the buffer and flip the sign of the source stride.
src_argb += src_stride_argb * (height - 1); src_argb += (ptrdiff_t)src_stride_argb * (height - 1);
src_stride_argb = -src_stride_argb; src_stride_argb = -src_stride_argb;
return ARGBTranspose(src_argb, src_stride_argb, dst_argb, dst_stride_argb, return ARGBTranspose(src_argb, src_stride_argb, dst_argb, dst_stride_argb,
width, height); width, height);
@ -101,7 +101,7 @@ static int ARGBRotate270(const uint8_t* src_argb,
// Rotate by 270 is a ARGBTranspose with the destination written // Rotate by 270 is a ARGBTranspose with the destination written
// from bottom to top. So set the destination pointer to the end // from bottom to top. So set the destination pointer to the end
// of the buffer and flip the sign of the destination stride. // of the buffer and flip the sign of the destination stride.
dst_argb += dst_stride_argb * (width - 1); dst_argb += (ptrdiff_t)dst_stride_argb * (width - 1);
dst_stride_argb = -dst_stride_argb; dst_stride_argb = -dst_stride_argb;
return ARGBTranspose(src_argb, src_stride_argb, dst_argb, dst_stride_argb, return ARGBTranspose(src_argb, src_stride_argb, dst_argb, dst_stride_argb,
width, height); width, height);
@ -114,8 +114,8 @@ static int ARGBRotate180(const uint8_t* src_argb,
int width, int width,
int height) { int height) {
// Swap first and last row and mirror the content. Uses a temporary row. // Swap first and last row and mirror the content. Uses a temporary row.
const uint8_t* src_bot = src_argb + src_stride_argb * (height - 1); const uint8_t* src_bot = src_argb + (ptrdiff_t)src_stride_argb * (height - 1);
uint8_t* dst_bot = dst_argb + dst_stride_argb * (height - 1); uint8_t* dst_bot = dst_argb + (ptrdiff_t)dst_stride_argb * (height - 1);
int half_height = (height + 1) >> 1; int half_height = (height + 1) >> 1;
int y; int y;
void (*ARGBMirrorRow)(const uint8_t* src_argb, uint8_t* dst_argb, int width) = void (*ARGBMirrorRow)(const uint8_t* src_argb, uint8_t* dst_argb, int width) =