Avoid issue AOMediaCodec/libavif#2886 avifRGBImagePremultiplyAlpha() and avifRGBImageUnpremultiplyAlpha() assume four-channel pixel buffers, so they would overrun the two-channel pixel buffer in an avifRGBImage of the AVIF_RGB_FORMAT_GRAYA or AVIF_RGB_FORMAT_AGRAY format. Return AVIF_RESULT_NOT_IMPLEMENTED before this bug is fixed. The bug was reported by Harrison Green. Avoids https://github.com/AOMediaCodec/libavif/issues/2886.
diff --git a/src/alpha.c b/src/alpha.c index f73400a..ec4976f 100644 --- a/src/alpha.c +++ b/src/alpha.c
@@ -165,6 +165,10 @@ return libyuvResult; } + if (rgb->format == AVIF_RGB_FORMAT_GRAYA || rgb->format == AVIF_RGB_FORMAT_AGRAY) { + return AVIF_RESULT_NOT_IMPLEMENTED; + } + assert(rgb->depth >= 8 && rgb->depth <= 16); uint32_t max = (1 << rgb->depth) - 1; @@ -280,6 +284,10 @@ return libyuvResult; } + if (rgb->format == AVIF_RGB_FORMAT_GRAYA || rgb->format == AVIF_RGB_FORMAT_AGRAY) { + return AVIF_RESULT_NOT_IMPLEMENTED; + } + assert(rgb->depth >= 8 && rgb->depth <= 16); uint32_t max = (1 << rgb->depth) - 1;
diff --git a/tests/gtest/avifalphapremtest.cc b/tests/gtest/avifalphapremtest.cc index 5c8bf8e..a1dc2fd 100644 --- a/tests/gtest/avifalphapremtest.cc +++ b/tests/gtest/avifalphapremtest.cc
@@ -1,6 +1,8 @@ // Copyright 2022 Google LLC // SPDX-License-Identifier: BSD-2-Clause +#include <string.h> + #include "avif/avif.h" #include "aviftest_helpers.h" #include "gtest/gtest.h" @@ -61,6 +63,22 @@ } } +TEST(AlphaMultiplyTest, GrayAImagePremultiplyAlpha) { + avifRGBImage rgb; + memset(&rgb, 0, sizeof(rgb)); + rgb.width = 6; + rgb.height = 1; + rgb.depth = 10; + rgb.format = AVIF_RGB_FORMAT_GRAYA; // 2 channels with alpha + ASSERT_EQ(avifRGBImageAllocatePixels(&rgb), AVIF_RESULT_OK); + memset(rgb.pixels, 1, (size_t)rgb.rowBytes * rgb.height); + // avifRGBImagePremultiplyAlpha assumes 4 channels and would overrun the + // 2-channel buffer. Until this bug (issue #2886) is fixed, it should return + // AVIF_RESULT_NOT_IMPLEMENTED. + EXPECT_EQ(avifRGBImagePremultiplyAlpha(&rgb), AVIF_RESULT_NOT_IMPLEMENTED); + avifRGBImageFreePixels(&rgb); +} + //------------------------------------------------------------------------------ } // namespace