Commit 531a0c4908 for ffmpeg

commit 531a0c4908f72f21856f64e68cb01d3fe794d1ed
Author: Michael Niedermayer <michael@niedermayer.cc>
Date:   Sun Oct 4 02:25:43 2026 +0200

    avformat/hls: attach ID3 pictures only for packed audio segments

    A leading ID3 tag is part of packed audio segments (AAC, MP3, AC-3 and
    E-AC-3, RFC 8216 section 3.4), but it is stripped and parsed from the first
    segment of audio and video playlists without an initialization section,
    whatever their format. Its pictures were added as new streams to the
    segment demuxer, and demuxers like mov dereference the private context of
    each of their streams, which is NULL for a stream they did not create.

    Fixes: NULL pointer dereference
    Fixes: tUVg3zZfpytx/testcase/list.m3u8 / gen.py
    Fixes: tUVg3zZfpytx
    Regression since: 01b184e68d
    Found during triage of the security report ANT-2026-HGVOM183
    Replicated through UnModified FFmpeg

diff --git a/libavformat/hls.c b/libavformat/hls.c
index 38d2a99fb2..5caf63b063 100644
--- a/libavformat/hls.c
+++ b/libavformat/hls.c
@@ -56,6 +56,8 @@
 #define MPEG_TIME_BASE 90000
 #define MPEG_TIME_BASE_Q (AVRational){1, MPEG_TIME_BASE}

+#define PACKED_AUDIO_FORMATS "aac,ac3,eac3,mp3"
+
 /*
  * An apple http stream consists of a playlist with media segment files,
  * played sequentially. There may be several playlists with the same
@@ -1311,9 +1313,10 @@ static void handle_id3(AVIOContext *pb, struct playlist *pls)
         pls->id3_found = 1;

         /* get picture attachment and set text metadata */
-        if (pls->ctx->nb_streams)
-            ff_id3v2_parse_apic(pls->ctx, extra_meta);
-        else
+        if (pls->ctx->nb_streams) {
+            if (av_match_name(pls->ctx->iformat->name, PACKED_AUDIO_FORMATS))
+                ff_id3v2_parse_apic(pls->ctx, extra_meta);
+        } else
             /* demuxer not yet opened, defer picture attachment */
             pls->id3_deferred_extra = extra_meta;

@@ -2562,7 +2565,8 @@ static int hls_read_header(AVFormatContext *s)
             return ret;

         if (pls->id3_deferred_extra && pls->ctx->nb_streams == 1) {
-            ff_id3v2_parse_apic(pls->ctx, pls->id3_deferred_extra);
+            if (av_match_name(pls->ctx->iformat->name, PACKED_AUDIO_FORMATS))
+                ff_id3v2_parse_apic(pls->ctx, pls->id3_deferred_extra);
             avformat_queue_attached_pictures(pls->ctx);
             ff_id3v2_parse_priv(pls->ctx, pls->id3_deferred_extra);
             ff_id3v2_free_extra_meta(&pls->id3_deferred_extra);