diff --git a/apps/shared/avifjpeg.c b/apps/shared/avifjpeg.c index 98cfbc3b6e..0ff015769f 100644 --- a/apps/shared/avifjpeg.c +++ b/apps/shared/avifjpeg.c @@ -22,6 +22,18 @@ #include #endif +#if defined(__clang__) && defined(__has_feature) +#if __has_feature(memory_sanitizer) +#include +#define AVIF_ANNOTATE_MEMORY_IS_INITIALIZED(address, size) __msan_unpoison(address, size) +#endif +#endif +#if !defined(AVIF_ANNOTATE_MEMORY_IS_INITIALIZED) +#define AVIF_ANNOTATE_MEMORY_IS_INITIALIZED(address, size) \ + do { \ + } while (0) +#endif + #define AVIF_MIN(a, b) (((a) < (b)) ? (a) : (b)) #define AVIF_MAX(a, b) (((a) > (b)) ? (a) : (b)) @@ -977,8 +989,11 @@ static avifBool avifJPEGReadInternal(FILE * f, int row = 0; while (cinfo.output_scanline < cinfo.output_height) { - jpeg_read_scanlines(&cinfo, buffer, 1); + if (jpeg_read_scanlines(&cinfo, buffer, 1) < 1) { + goto cleanup; + } uint8_t * pixelRow = &rgb.pixels[row * rgb.rowBytes]; + AVIF_ANNOTATE_MEMORY_IS_INITIALIZED(buffer[0], rgb.rowBytes); memcpy(pixelRow, buffer[0], rgb.rowBytes); ++row; } @@ -1344,10 +1359,12 @@ avifBool avifJPEGWrite(const char * outputFilename, const avifImage * avif, int avifROData remainingExif = { exif.data, exif.size }; while (remainingExif.size > AVIF_JPEG_MAX_MARKER_DATA_LENGTH) { + AVIF_ANNOTATE_MEMORY_IS_INITIALIZED(remainingExif.data, AVIF_JPEG_MAX_MARKER_DATA_LENGTH); jpeg_write_marker(&cinfo, JPEG_APP0 + 1, remainingExif.data, AVIF_JPEG_MAX_MARKER_DATA_LENGTH); remainingExif.data += AVIF_JPEG_MAX_MARKER_DATA_LENGTH; remainingExif.size -= AVIF_JPEG_MAX_MARKER_DATA_LENGTH; } + AVIF_ANNOTATE_MEMORY_IS_INITIALIZED(remainingExif.data, remainingExif.size); jpeg_write_marker(&cinfo, JPEG_APP0 + 1, remainingExif.data, (unsigned int)remainingExif.size); avifRWDataFree(&exif); } else if (avifImageGetExifOrientationFromIrotImir(avif) != 1) { @@ -1379,6 +1396,7 @@ avifBool avifJPEGWrite(const char * outputFilename, const avifImage * avif, int } memcpy(xmp.data, AVIF_JPEG_STANDARD_XMP_TAG, AVIF_JPEG_STANDARD_XMP_TAG_LENGTH); memcpy(xmp.data + AVIF_JPEG_STANDARD_XMP_TAG_LENGTH, avif->xmp.data, avif->xmp.size); + AVIF_ANNOTATE_MEMORY_IS_INITIALIZED(xmp.data, xmp.size); jpeg_write_marker(&cinfo, JPEG_APP0 + 1, xmp.data, (unsigned int)xmp.size); avifRWDataFree(&xmp); } @@ -1386,7 +1404,9 @@ avifBool avifJPEGWrite(const char * outputFilename, const avifImage * avif, int while (cinfo.next_scanline < cinfo.image_height) { row_pointer[0] = &rgb.pixels[cinfo.next_scanline * rgb.rowBytes]; - (void)jpeg_write_scanlines(&cinfo, row_pointer, 1); + if (jpeg_write_scanlines(&cinfo, row_pointer, 1) < 1) { + goto cleanup; + } } jpeg_finish_compress(&cinfo); diff --git a/include/avif/internal.h b/include/avif/internal.h index ccee529955..a8971ac17c 100644 --- a/include/avif/internal.h +++ b/include/avif/internal.h @@ -6,6 +6,19 @@ #include "avif/avif.h" // IWYU pragma: export +#if defined(__clang__) && defined(__has_feature) +#if __has_feature(memory_sanitizer) +#include +#define AVIF_ANNOTATE_MEMORY_IS_INITIALIZED(address, size) __msan_unpoison(address, size) +#endif +#endif + +#if !defined(AVIF_ANNOTATE_MEMORY_IS_INITIALIZED) +#define AVIF_ANNOTATE_MEMORY_IS_INITIALIZED(address, size) \ + do { \ + } while (0) +#endif + #ifdef __cplusplus extern "C" { #endif diff --git a/src/codec_aom.c b/src/codec_aom.c index 396c32f40a..340b63a134 100644 --- a/src/codec_aom.c +++ b/src/codec_aom.c @@ -1144,6 +1144,7 @@ static avifResult aomCodecEncodeImage(avifCodec * codec, break; } if (pkt->kind == AOM_CODEC_CX_FRAME_PKT) { + AVIF_ANNOTATE_MEMORY_IS_INITIALIZED(pkt->data.frame.buf, pkt->data.frame.sz); AVIF_CHECKRES( avifCodecEncodeOutputAddSample(output, pkt->data.frame.buf, pkt->data.frame.sz, (pkt->data.frame.flags & AOM_FRAME_IS_KEY))); }