Commit 52b653190c for ffmpeg

commit 52b653190c001e132ef35ee6f113b0f413d16e79
Author: Michael Niedermayer <michael@niedermayer.cc>
Date:   Thu Oct 8 07:31:26 2026 +0200

    avformat/nut: Fix files with many streams

    The demuxer rejected files with more than 256 streams, it now uses
    max_streams as the limit and stores frame code stream ids as int.

    The invalid stream ids and the stream limit of the demuxer were found
    during triage of the security report.

    Fixes: out of array access
    Fixes: 0tstIJT8grvU
    Fixes: AISLE-2026-0111-00174
    Out of array read Replicated through UnModified FFmpeg with ASAN
    Fixes: lPmeH2OaqLeE
    Invalid frame code stream ids Replicated through UnModified FFmpeg
    Fixes: OyhhaqyPDH4L
    Unreadable output Replicated through UnModified FFmpeg
    Found-by: Joshua Rogers <joshua.rogers@aisle.com>

diff --git a/libavformat/nut.h b/libavformat/nut.h
index a4409ee23d..6d1100d7ea 100644
--- a/libavformat/nut.h
+++ b/libavformat/nut.h
@@ -64,7 +64,7 @@ typedef struct Syncpoint {

 typedef struct FrameCode {
     uint16_t flags;
-    uint8_t  stream_id;
+    int      stream_id;
     uint16_t size_mul;
     uint16_t size_lsb;
     int16_t  pts_delta;
diff --git a/libavformat/nutdec.c b/libavformat/nutdec.c
index b0a997cad6..7ec8526a06 100644
--- a/libavformat/nutdec.c
+++ b/libavformat/nutdec.c
@@ -36,8 +36,6 @@
 #include "nut.h"
 #include "riff.h"

-#define NUT_MAX_STREAMS 256    /* arbitrary sanity check value */
-
 static int64_t nut_read_timestamp(AVFormatContext *s, int stream_index,
                                   int64_t *pos_arg, int64_t pos_limit);

@@ -216,7 +214,7 @@ static int decode_main_header(NUTContext *nut)
     if (nut->version > 3)
         nut->minor_version = ffio_read_varlen(bc);

-    GET_V(stream_count, tmp > 0 && tmp <= NUT_MAX_STREAMS);
+    GET_V(stream_count, tmp > 0 && tmp <= s->max_streams);

     nut->max_distance = ffio_read_varlen(bc);
     if (nut->max_distance > 65536) {
diff --git a/libavformat/nutenc.c b/libavformat/nutenc.c
index 55efb114c3..a7173b65f9 100644
--- a/libavformat/nutenc.c
+++ b/libavformat/nutenc.c
@@ -188,9 +188,12 @@ static void build_frame_code(AVFormatContext *s)
         start++;
     }

-    for (stream_id = 0; stream_id < s->nb_streams; stream_id++) {
-        int start2 = start + (end - start) * stream_id       / s->nb_streams;
-        int end2   = start + (end - start) * (stream_id + 1) / s->nb_streams;
+    /* Each stream needs up to 6 frame codes, streams beyond use the escape frame codes */
+    int nb_frame_code_streams = FFMIN(s->nb_streams, (end - start) / 6);
+
+    for (stream_id = 0; stream_id < nb_frame_code_streams; stream_id++) {
+        int start2 = start + (end - start) * stream_id       / nb_frame_code_streams;
+        int end2   = start + (end - start) * (stream_id + 1) / nb_frame_code_streams;
         AVCodecParameters *par        = s->streams[stream_id]->codecpar;
         int is_audio                  = par->codec_type == AVMEDIA_TYPE_AUDIO;
         int intra_only        = /*codec->intra_only || */ is_audio;