Commit 90d45b94f6 for ffmpeg

commit 90d45b94f610555ecee8d86e2ebdefab8b1454a7
Author: Michael Niedermayer <michael@niedermayer.cc>
Date:   Sat Oct 10 06:45:00 2026 +0200

    avformat/sbgdec: bound the number of events a script expands to

    Out of memory Replicated through API

    Found during triage/review of OSS-Fuzz issue 474457174

    Fixes: out of memory
    Fixes: Cw8GY4kWak6W/b24.sbg / gen_b.py
    Fixes: Cw8GY4kWak6W

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

diff --git a/libavformat/sbgdec.c b/libavformat/sbgdec.c
index fb5593511b..9920007d7f 100644
--- a/libavformat/sbgdec.c
+++ b/libavformat/sbgdec.c
@@ -945,7 +945,8 @@ static int expand_timestamps(void *log, struct sbg_script *s)
 }

 static int expand_tseq(void *log, struct sbg_script *s, int *nb_ev_max,
-                       int64_t t0, struct sbg_script_tseq *tseq)
+                       int64_t max_events, int64_t t0,
+                       struct sbg_script_tseq *tseq)
 {
     int i, r;
     struct sbg_script_definition *def;
@@ -975,11 +976,15 @@ static int expand_tseq(void *log, struct sbg_script *s, int *nb_ev_max,
     if (def->type == 'B') {
         be = s->block_tseq + def->elements;
         for (i = 0; i < def->nb_elements; i++) {
-            r = expand_tseq(log, s, nb_ev_max, t0, &be[i]);
+            r = expand_tseq(log, s, nb_ev_max, max_events, t0, &be[i]);
             if (r < 0)
                 return r;
         }
     } else {
+        if (s->nb_events >= max_events) {
+            av_log(log, AV_LOG_ERROR, "Too many events\n");
+            return AVERROR_INVALIDDATA;
+        }
         ev = alloc_array_elem((void **)&s->events, sizeof(*ev),
                               &s->nb_events, nb_ev_max);
         if (!ev)
@@ -993,7 +998,7 @@ static int expand_tseq(void *log, struct sbg_script *s, int *nb_ev_max,
     return 0;
 }

-static int expand_script(void *log, struct sbg_script *s)
+static int expand_script(void *log, struct sbg_script *s, int64_t max_events)
 {
     int i, r, nb_events_max = 0;

@@ -1001,7 +1006,7 @@ static int expand_script(void *log, struct sbg_script *s)
     if (r < 0)
         return r;
     for (i = 0; i < s->nb_tseq; i++) {
-        r = expand_tseq(log, s, &nb_events_max, 0, &s->tseq[i]);
+        r = expand_tseq(log, s, &nb_events_max, max_events, 0, &s->tseq[i]);
         if (r < 0)
             return r;
     }
@@ -1426,7 +1431,7 @@ static av_cold int sbg_read_header(AVFormatContext *avf)
     if (script.opt_mix)
         av_log(avf, AV_LOG_WARNING, "Mix feature not implemented: "
                "-m is ignored and mix channels will be silent.\n");
-    r = expand_script(avf, &script);
+    r = expand_script(avf, &script, 4 * (int64_t)bprint.len + 16384);
     if (r < 0)
         goto fail2;
     av_bprint_finalize(&bprint, NULL);