Commit 6b0b15b0d6 for ffmpeg

commit 6b0b15b0d6d0344b295395fccd0db642049df20e
Author: Michael Niedermayer <michael@niedermayer.cc>
Date:   Sun Oct 25 05:48:24 2026 +0100

    avcodec/dovi_rpuenc: reject metadata with more extension blocks than the cache holds

    Fixes: EMtBgkYsAzTJ/testcase/dovi_ext_overflow.c
    Fixes: EMtBgkYsAzTJ
    Fixes: out of array write
    Out of array write Replicated through API with ASAN

    Found during the review of PR 25408.

    Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>

diff --git a/libavcodec/dovi_rpuenc.c b/libavcodec/dovi_rpuenc.c
index bdda95f991..2e567ad751 100644
--- a/libavcodec/dovi_rpuenc.c
+++ b/libavcodec/dovi_rpuenc.c
@@ -651,7 +651,7 @@ int ff_dovi_rpu_generate(DOVIContext *s, const AVDOVIMetadata *metadata,
     const AVDOVIColorMetadata *color;
     int vdr_dm_metadata_present, vdr_rpu_id, use_prev_vdr_rpu, profile,
         buffer_size, rpu_size, pad, zero_run, dm_compression;
-    int num_ext_blocks_v1, num_ext_blocks_v2;
+    int num_ext_blocks_v1, num_ext_blocks_v2, num_static, num_dynamic;
     int dv_md_compression = s->cfg.dv_md_compression;
     uint32_t crc;
     uint8_t *dst;
@@ -744,10 +744,15 @@ int ff_dovi_rpu_generate(DOVIContext *s, const AVDOVIMetadata *metadata,
     }

     num_ext_blocks_v1 = num_ext_blocks_v2 = 0;
+    num_static = num_dynamic = 0;
     for (int i = 0; i < metadata->num_ext_blocks; i++) {
         const AVDOVIDmData *dm = av_dovi_get_ext(metadata, i);
-        if (dm_compression && ff_dovi_rpu_extension_is_static(dm->level))
-            continue;
+        if (ff_dovi_rpu_extension_is_static(dm->level)) {
+            num_static++;
+            if (dm_compression)
+                continue;
+        } else
+            num_dynamic++;

         switch (dm->level) {
         case 1:
@@ -772,6 +777,12 @@ int ff_dovi_rpu_generate(DOVIContext *s, const AVDOVIMetadata *metadata,
             return AVERROR_INVALIDDATA;
         }
     }
+    if (num_static  > FF_ARRAY_ELEMS(s->ext_blocks->dm_static) ||
+        num_dynamic > FF_ARRAY_ELEMS(s->ext_blocks->dm_dynamic)) {
+        av_log(s->logctx, AV_LOG_ERROR, "Too many ext blocks: %d static, %d dynamic\n",
+               num_static, num_dynamic);
+        return AVERROR_INVALIDDATA;
+    }

     buffer_size = 12 /* vdr seq info */ + 5 /* CRC32 + terminator */;
     buffer_size += num_ext_blocks_v1 * 13;