From 2448daefb66b4aadfa76c42eb8d7895e94df07df Mon Sep 17 00:00:00 2001
From: Jakub Janecek <[email protected]>
Date: Thu, 9 Apr 2026 15:46:27 +0200
Subject: [PATCH] avformat/hls: fix segfault on EXT-X-MEDIA playlist with no
 segments

The broken-marking loop after playlist parsing only iterated over
c->n_variants, covering only the primary EXT-X-STREAM-INF playlists.
EXT-X-MEDIA rendition playlists, which live in c->playlists but have
no corresponding c->variants entry, were not covered.

As a result, when a rendition playlist had no segments, it was not
marked broken, playlist_needed() returned 1 for it (due to
n_main_streams == 0), and recheck_discard_flags() marked it needed.
Meanwhile, its AVFormatContext had been allocated by
avformat_alloc_context() but the demuxer open loop immediately
continued before calling avformat_open_input(), leaving iformat as
NULL. hls_read_packet() then called av_read_frame() on the
uninitialized context, crashing on the NULL iformat->read_packet
dereference.

Fix by extending the broken-marking loop from c->n_variants to
c->n_playlists so rendition playlists with no segments are also marked
broken and skipped. Move the avformat_alloc_context() call to after
the n_segments == 0 check to avoid allocating a context that is
immediately abandoned.

Signed-off-by: Jakub Janecek <[email protected]>
---
 libavformat/hls.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/libavformat/hls.c b/libavformat/hls.c
index 28c883097a..0eb18f5852 100644
--- a/libavformat/hls.c
+++ b/libavformat/hls.c
@@ -2175,10 +2175,10 @@ static int hls_read_header(AVFormatContext *s)
         }
     }

-    for (i = 0; i < c->n_variants; i++) {
-        if (c->variants[i]->playlists[0]->n_segments == 0) {
-            av_log(s, AV_LOG_WARNING, "Empty segment [%s]\n", 
c->variants[i]->playlists[0]->url);
-            c->variants[i]->playlists[0]->broken = 1;
+    for (i = 0; i < c->n_playlists; i++) {
+        if (c->playlists[i]->n_segments == 0) {
+            av_log(s, AV_LOG_WARNING, "Empty playlist [%s]\n", 
c->playlists[i]->url);
+            c->playlists[i]->broken = 1;
         }
     }

@@ -2235,12 +2235,12 @@ static int hls_read_header(AVFormatContext *s)
         AVDictionary *options = NULL;
         struct segment *seg = NULL;

-        if (!(pls->ctx = avformat_alloc_context()))
-            return AVERROR(ENOMEM);
-
         if (pls->n_segments == 0)
             continue;

+        if (!(pls->ctx = avformat_alloc_context()))
+            return AVERROR(ENOMEM);
+
         pls->index  = i;
         pls->needed = 1;
         pls->parent = s;
--
2.52.0

_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to