Skip to content

Commit d14b742

Browse files
committed
Fix uint32_t overflow of row offsets in avifImageYUVAnyToRGBAnySlow
In the slow YUV-to-RGB fallback in src/reformat.c, the Y/U/V/A row pointers were computed with 'j * yRowBytes' style multiplications where both operands are uint32_t. For images whose plane size exceeds 4 GiB the product wraps around and the loop reads from a different row of the same buffer, producing silently corrupted output. Cast the row index to size_t before the multiplication so the offset is computed in size_t arithmetic, matching what is already done for the RGB destination pointers a few lines below and the same pattern applied in c79a400.
1 parent 3c66271 commit d14b742

2 files changed

Lines changed: 6 additions & 4 deletions

File tree

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ The changes are relative to the previous release, unless the baseline is specifi
2323
* Update svt.cmd/svt.sh/LocalSvt.cmake: v4.1.0
2424
* Fix decoding layered image with multiple scaled alpha layers
2525
* Fix NaN bypass of AVIF_CLAMP in gain map tone mapping (use fminf/fmaxf)
26+
* Fix uint32_t overflow in row offset arithmetic in
27+
avifImageYUVAnyToRGBAnySlow().
2628
* avifenc: reject mismatched --depth for Y4M input
2729
* Use libaom AOMD_SET_FRAME_SIZE_LIMIT if available
2830

src/reformat.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -686,10 +686,10 @@ static avifResult avifImageYUVAnyToRGBAnySlow(const avifImage * image,
686686
for (uint32_t j = 0; j < image->height; ++j) {
687687
// uvJ is used only when yuvHasColor is true.
688688
const uint32_t uvJ = yuvHasColor ? (j >> state->yuv.formatInfo.chromaShiftY) : 0;
689-
const uint8_t * ptrY8 = &yPlane[j * yRowBytes];
690-
const uint8_t * ptrU8 = uPlane ? &uPlane[(uvJ * uRowBytes)] : NULL;
691-
const uint8_t * ptrV8 = vPlane ? &vPlane[(uvJ * vRowBytes)] : NULL;
692-
const uint8_t * ptrA8 = aPlane ? &aPlane[j * aRowBytes] : NULL;
689+
const uint8_t * ptrY8 = &yPlane[(size_t)j * yRowBytes];
690+
const uint8_t * ptrU8 = uPlane ? &uPlane[((size_t)uvJ * uRowBytes)] : NULL;
691+
const uint8_t * ptrV8 = vPlane ? &vPlane[((size_t)uvJ * vRowBytes)] : NULL;
692+
const uint8_t * ptrA8 = aPlane ? &aPlane[(size_t)j * aRowBytes] : NULL;
693693
const uint16_t * ptrY16 = (const uint16_t *)ptrY8;
694694
const uint16_t * ptrU16 = (const uint16_t *)ptrU8;
695695
const uint16_t * ptrV16 = (const uint16_t *)ptrV8;

0 commit comments

Comments
 (0)