avifImageCopy: check avifImageCreateEmpty() result
When the destination image has no gain map image yet but the source
does, avifImageCopy() called avifImageCreateEmpty() and passed the
result to a recursive avifImageCopy() without checking for allocation
failure. Under out-of-memory conditions this dereferenced a NULL pointer
in avifImageFreePlanes() at the start of the recursive call.
Add the missing AVIF_CHECKERR, matching the existing pattern used for
the avifGainMapCreate() allocation a few lines above.
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9d381aa..261f72c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -23,6 +23,8 @@
* Update svt.cmd/svt.sh/LocalSvt.cmake: v4.1.0
* Fix decoding layered image with multiple scaled alpha layers
* Fix NaN bypass of AVIF_CLAMP in gain map tone mapping (use fminf/fmaxf)
+* Fix null pointer dereference in avifImageCopy() when avifImageCreateEmpty()
+ fails to allocate the destination gain map image.
* avifenc: reject mismatched --depth for Y4M input
* Use libaom AOMD_SET_FRAME_SIZE_LIMIT if available
diff --git a/src/avif.c b/src/avif.c
index 93d5377..f44dc49 100644
--- a/src/avif.c
+++ b/src/avif.c
@@ -305,6 +305,7 @@
if (srcImage->gainMap->image) {
if (!dstImage->gainMap->image) {
dstImage->gainMap->image = avifImageCreateEmpty();
+ AVIF_CHECKERR(dstImage->gainMap->image, AVIF_RESULT_OUT_OF_MEMORY);
}
AVIF_CHECKRES(avifImageCopy(dstImage->gainMap->image, srcImage->gainMap->image, planes));
} else if (dstImage->gainMap->image) {