Skip to content

Commit 8ea8f53

Browse files
committed
overflow checks and size_t casts
1 parent dc8d99c commit 8ea8f53

4 files changed

Lines changed: 33 additions & 27 deletions

File tree

src/codec_aom.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1210,7 +1210,7 @@ static avifResult aomCodecEncodeImage(avifCodec * codec,
12101210
const uint32_t bytesPerRow = ((image->depth > 8) ? 2 : 1) * image->width;
12111211
for (uint32_t j = 0; j < image->height; ++j) {
12121212
const uint8_t * srcAlphaRow = &image->alphaPlane[(size_t)j * image->alphaRowBytes];
1213-
uint8_t * dstAlphaRow = &aomImage.planes[0][j * aomImage.stride[0]];
1213+
uint8_t * dstAlphaRow = &aomImage.planes[0][(size_t)j * aomImage.stride[0]];
12141214
memcpy(dstAlphaRow, srcAlphaRow, bytesPerRow);
12151215
}
12161216
} else {
@@ -1234,7 +1234,7 @@ static avifResult aomCodecEncodeImage(avifCodec * codec,
12341234

12351235
for (uint32_t j = 0; j < planeHeight; ++j) {
12361236
const uint8_t * srcRow = &image->yuvPlanes[yuvPlane][(size_t)j * image->yuvRowBytes[yuvPlane]];
1237-
uint8_t * dstRow = &aomImage.planes[yuvPlane][j * aomImage.stride[yuvPlane]];
1237+
uint8_t * dstRow = &aomImage.planes[yuvPlane][(size_t)j * aomImage.stride[yuvPlane]];
12381238
memcpy(dstRow, srcRow, bytesPerRow);
12391239
}
12401240
}

src/codec_avm.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -904,7 +904,7 @@ static avifResult avmCodecEncodeImage(avifCodec * codec,
904904
const uint32_t bytesPerRow = ((image->depth > 8) ? 2 : 1) * image->width;
905905
for (uint32_t j = 0; j < image->height; ++j) {
906906
const uint8_t * srcAlphaRow = &image->alphaPlane[(size_t)j * image->alphaRowBytes];
907-
uint8_t * dstAlphaRow = &avmImage.planes[0][j * avmImage.stride[0]];
907+
uint8_t * dstAlphaRow = &avmImage.planes[0][(size_t)j * avmImage.stride[0]];
908908
memcpy(dstAlphaRow, srcAlphaRow, bytesPerRow);
909909
}
910910
} else {
@@ -928,7 +928,7 @@ static avifResult avmCodecEncodeImage(avifCodec * codec,
928928

929929
for (uint32_t j = 0; j < planeHeight; ++j) {
930930
const uint8_t * srcRow = &image->yuvPlanes[yuvPlane][(size_t)j * image->yuvRowBytes[yuvPlane]];
931-
uint8_t * dstRow = &avmImage.planes[yuvPlane][j * avmImage.stride[yuvPlane]];
931+
uint8_t * dstRow = &avmImage.planes[yuvPlane][(size_t)j * avmImage.stride[yuvPlane]];
932932
memcpy(dstRow, srcRow, bytesPerRow);
933933
}
934934
}

src/codec_svt.c

Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -274,26 +274,21 @@ static avifResult svtCodecEncodeImage(avifCodec * codec,
274274
if (alpha) {
275275
input_picture_buffer->y_stride = image->alphaRowBytes / bytesPerPixel;
276276
input_picture_buffer->luma = image->alphaPlane;
277-
input_buffer->n_filled_len = (uint32_t)((size_t)image->alphaRowBytes * image->height);
277+
const size_t alphaSize = (size_t)image->alphaRowBytes * image->height;
278+
if (alphaSize > UINT32_MAX) {
279+
goto cleanup;
280+
}
281+
input_buffer->n_filled_len = (uint32_t)alphaSize;
278282

279283
#if SVT_AV1_CHECK_VERSION(1, 8, 0)
280284
// Simulate 4:2:0 UV planes. SVT-AV1 does not support 4:0:0 samples.
281-
const size_t uvWidth = ((size_t)image->width + y_shift) >> y_shift;
282-
283-
// Use size_t to avoid 32-bit overflow
284-
const size_t uvRowBytes = (size_t)uvWidth * (size_t)bytesPerPixel;
285-
286-
// Verify multiplication overflow
287-
if (uvWidth != 0 &&
288-
uvRowBytes / (size_t)uvWidth != (size_t)bytesPerPixel) {
285+
const uint32_t uvWidth = (image->width + y_shift) >> y_shift;
286+
const uint32_t uvRowBytes = uvWidth * bytesPerPixel;
287+
const size_t uvSize = (size_t)uvRowBytes * uvHeight;
288+
if (uvSize > UINT32_MAX / 2) {
289289
goto cleanup;
290290
}
291-
292-
const size_t uvSize = uvRowBytes * (size_t)uvHeight;
293-
294-
// Verify second multiplication overflow
295-
if (uvHeight != 0 &&
296-
uvSize / (size_t)uvHeight != uvRowBytes) {
291+
if (uvSize * 2 > UINT32_MAX - input_buffer->n_filled_len) {
297292
goto cleanup;
298293
}
299294
uvPlanes = avifAlloc(uvSize);
@@ -305,8 +300,8 @@ static avifResult svtCodecEncodeImage(avifCodec * codec,
305300
input_buffer->n_filled_len += (uint32_t)uvSize;
306301
input_picture_buffer->cr = uvPlanes;
307302
input_buffer->n_filled_len += (uint32_t)uvSize;
308-
input_picture_buffer->cb_stride = (uint32_t)uvWidth;
309-
input_picture_buffer->cr_stride = (uint32_t)uvWidth;
303+
input_picture_buffer->cb_stride = uvWidth;
304+
input_picture_buffer->cr_stride = uvWidth;
310305
#else
311306
// This workaround was not needed before SVT-AV1 1.8.0.
312307
// See https://github.com/AOMediaCodec/libavif/issues/1992.
@@ -315,11 +310,23 @@ static avifResult svtCodecEncodeImage(avifCodec * codec,
315310
} else {
316311
input_picture_buffer->y_stride = image->yuvRowBytes[0] / bytesPerPixel;
317312
input_picture_buffer->luma = image->yuvPlanes[0];
318-
input_buffer->n_filled_len = (uint32_t)((size_t)image->yuvRowBytes[0] * image->height);
313+
const size_t ySize = (size_t)image->yuvRowBytes[0] * image->height;
314+
if (ySize > UINT32_MAX) {
315+
goto cleanup;
316+
}
317+
input_buffer->n_filled_len = (uint32_t)ySize;
319318
input_picture_buffer->cb = image->yuvPlanes[1];
320-
input_buffer->n_filled_len += (uint32_t)((size_t)image->yuvRowBytes[1] * uvHeight);
319+
const size_t uSize = (size_t)image->yuvRowBytes[1] * uvHeight;
320+
if (uSize > UINT32_MAX - input_buffer->n_filled_len) {
321+
goto cleanup;
322+
}
323+
input_buffer->n_filled_len += (uint32_t)uSize;
321324
input_picture_buffer->cr = image->yuvPlanes[2];
322-
input_buffer->n_filled_len += (uint32_t)((size_t)image->yuvRowBytes[2] * uvHeight);
325+
const size_t vSize = (size_t)image->yuvRowBytes[2] * uvHeight;
326+
if (vSize > UINT32_MAX - input_buffer->n_filled_len) {
327+
goto cleanup;
328+
}
329+
input_buffer->n_filled_len += (uint32_t)vSize;
323330
input_picture_buffer->cb_stride = image->yuvRowBytes[1] / bytesPerPixel;
324331
input_picture_buffer->cr_stride = image->yuvRowBytes[2] / bytesPerPixel;
325332
}

src/reformat.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1854,8 +1854,7 @@ void avifGetRGBAPixel(const avifRGBImage * src, uint32_t x, uint32_t y, const av
18541854
assert(!src->isFloat || src->depth == 16);
18551855
assert(src->format != AVIF_RGB_FORMAT_RGB_565 || src->depth == 8);
18561856

1857-
const size_t offset = (size_t)y * (size_t)src->rowBytes + (size_t)x * (size_t)info->pixelBytes;
1858-
const uint8_t * const srcPixel = &src->pixels[offset];
1857+
const uint8_t * const srcPixel = &src->pixels[(size_t)y * src->rowBytes + (size_t)x * info->pixelBytes];
18591858
if (info->channelBytes > 1) {
18601859
uint16_t r = *((const uint16_t *)(&srcPixel[info->offsetBytesR]));
18611860
uint16_t g = *((const uint16_t *)(&srcPixel[info->offsetBytesG]));
@@ -1898,7 +1897,7 @@ void avifSetRGBAPixel(const avifRGBImage * dst, uint32_t x, uint32_t y, const av
18981897
assert(rgbaPixel[1] >= 0.0f && rgbaPixel[1] <= 1.0f);
18991898
assert(rgbaPixel[2] >= 0.0f && rgbaPixel[2] <= 1.0f);
19001899

1901-
uint8_t * const dstPixel = &dst->pixels[(size_t)y * dst->rowBytes + x * info->pixelBytes];
1900+
uint8_t * const dstPixel = &dst->pixels[(size_t)y * dst->rowBytes + (size_t)x * info->pixelBytes];
19021901

19031902
uint8_t * const ptrR = &dstPixel[info->offsetBytesR];
19041903
uint8_t * const ptrG = &dstPixel[info->offsetBytesG];

0 commit comments

Comments
 (0)