PR #25553 opened by Romain Beauxis (toots)
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25553
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25553.patch


>From 8411cd9e71aa7df4cd0f1e68141f839562079687 Mon Sep 17 00:00:00 2001
From: Michael Niedermayer <[email protected]>
Date: Tue, 6 Oct 2026 07:33:05 +0200
Subject: [PATCH 1/2] avformat/oggenc: Reset the current page when it cannot be
 buffered

On allocation failure the full page stayed in the stream context, and
the next segment was added past its 255 entry segment table.

Fixes: out of array access
Fixes: flOsaBhTFc6F
Fixes: AISLE-2026-0111-00072
Negative size memset Replicated through API with ASAN and av_max_alloc() 
lowered after the header
Found-by: Joshua Rogers <[email protected]>

(cherry picked from commit 6d40aa17395aaba80922441bcfb58399a88475e3)
---
 libavformat/oggenc.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/libavformat/oggenc.c b/libavformat/oggenc.c
index 605c9d20e14..84d1705e902 100644
--- a/libavformat/oggenc.c
+++ b/libavformat/oggenc.c
@@ -201,8 +201,10 @@ static int ogg_buffer_page(AVFormatContext *s, 
OGGStreamContext *oggstream)
     OGGPageList **p = &ogg->page_list;
     OGGPageList *l = av_mallocz(sizeof(*l));
 
-    if (!l)
+    if (!l) {
+        ogg_reset_cur_page(oggstream);
         return AVERROR(ENOMEM);
+    }
     l->page = oggstream->page;
 
     oggstream->page.start_granule = ogg_granule_to_timestamp(oggstream, 
oggstream->page.granule);
-- 
2.54.0


>From 7afd1202aec0eea48610b8bca229503a9c72654c Mon Sep 17 00:00:00 2001
From: Martin Mirchev <[email protected]>
Date: Tue, 27 Oct 2026 11:49:49 +0800
Subject: [PATCH 2/2] avformat/oggparsevorbis: fix chained streams with headers
 over 64 KiB

When a chained Vorbis stream starts, its three header packets are
packed into new extradata with 16-bit size prefixes. A header larger
than 65535 bytes, typically a comment header with embedded cover art,
gets its size truncated, so the Vorbis parser cannot be reinitialized
and demuxing fails with "Failed to re-initialize Vorbis parser". The
audio of the new chained stream and everything after it is lost.

Use Xiph lacing instead, as vorbis_header() already does for the
initial extradata.

Signed-off-by: Martin Mirchev <[email protected]>
(cherry picked from commit 94110fbc39a85f442530fc73d5c9b906d2551244)
---
 libavformat/oggparsevorbis.c | 29 ++++++++++++++++++++---------
 1 file changed, 20 insertions(+), 9 deletions(-)

diff --git a/libavformat/oggparsevorbis.c b/libavformat/oggparsevorbis.c
index 4044ad3bf75..71de123a941 100644
--- a/libavformat/oggparsevorbis.c
+++ b/libavformat/oggparsevorbis.c
@@ -458,7 +458,6 @@ static int vorbis_packet(AVFormatContext *s, int idx)
     int duration, flags = 0;
     int skip_packet = 0;
     int ret, new_extradata_size;
-    PutByteContext pb;
 
     if (!priv->vp)
         return AVERROR_INVALIDDATA;
@@ -587,20 +586,32 @@ static int vorbis_packet(AVFormatContext *s, int idx)
     }
 
     if (priv->header && priv->comment && priv->setup) {
-        new_extradata_size = priv->header_size + priv->comment_size + 
priv->setup_size + 6;
+        uint64_t total_size = (uint64_t)priv->header_size + priv->comment_size 
+
+                              priv->setup_size;
+        uint8_t *p;
+
+        /* Use Xiph lacing like vorbis_header() does: 16-bit sizes cannot
+         * describe headers larger than 64 KiB, e.g. a comment header with
+         * embedded cover art. */
+        if (total_size + total_size / 255 + 3 > INT_MAX)
+            return AVERROR_INVALIDDATA;
+        new_extradata_size = 1 + priv->header_size / 255 + 1 +
+                             priv->comment_size / 255 + 1 + total_size;
 
         ret = av_reallocp(&os->new_extradata, new_extradata_size);
         if (ret < 0)
             return ret;
 
         os->new_extradata_size = new_extradata_size;
-        bytestream2_init_writer(&pb, os->new_extradata, new_extradata_size);
-        bytestream2_put_be16(&pb, priv->header_size);
-        bytestream2_put_buffer(&pb, priv->header, priv->header_size);
-        bytestream2_put_be16(&pb, priv->comment_size);
-        bytestream2_put_buffer(&pb, priv->comment, priv->comment_size);
-        bytestream2_put_be16(&pb, priv->setup_size);
-        bytestream2_put_buffer(&pb, priv->setup, priv->setup_size);
+        p     = os->new_extradata;
+        *p++  = 2;
+        p    += av_xiphlacing(p, priv->header_size);
+        p    += av_xiphlacing(p, priv->comment_size);
+        memcpy(p, priv->header, priv->header_size);
+        p    += priv->header_size;
+        memcpy(p, priv->comment, priv->comment_size);
+        p    += priv->comment_size;
+        memcpy(p, priv->setup, priv->setup_size);
 
         av_freep(&priv->header);
         priv->header_size = 0;
-- 
2.54.0

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

Reply via email to