PR #21608 opened by mkver
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/21608
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/21608.patch

caf_write_deinit() would segfault if the CAFStreamContext
couldn't be allocated. Fix this by moving everything from
CAFStreamContext to the ordinary CAFContext; the separation
doesn't make sense for a format with only one stream anyway
and removing it also avoids an indirection.


>From 4367c055b6b253e97be603b0d1e58ce841abd1b8 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <[email protected]>
Date: Fri, 30 Jan 2026 11:30:30 +0100
Subject: [PATCH] avformat/cafenc: Fix segfault upon error, avoid indirection

caf_write_deinit() would segfault if the CAFStreamContext
couldn't be allocated. Fix this by moving everything from
CAFStreamContext to the ordinary CAFContext; the separation
doesn't make sense for a format with only one stream anyway
and removing it also avoids an indirection.

Signed-off-by: Andreas Rheinhardt <[email protected]>
---
 libavformat/cafenc.c | 50 ++++++++++++++++++--------------------------
 1 file changed, 20 insertions(+), 30 deletions(-)

diff --git a/libavformat/cafenc.c b/libavformat/cafenc.c
index 5bee5f74bb..3a3493717d 100644
--- a/libavformat/cafenc.c
+++ b/libavformat/cafenc.c
@@ -35,14 +35,12 @@ typedef struct {
     int64_t total_duration;
     int64_t packets;
     uint32_t frame_size;
-} CAFContext;
 
-typedef struct {
     uint32_t *byte_size_buffer;
     uint32_t *frame_size_buffer;
     unsigned byte_size_buffer_sz;
     unsigned frame_size_buffer_sz;
-} CAFStreamContext;
+} CAFContext;
 
 static uint32_t codec_flags(enum AVCodecID codec_id) {
     switch (codec_id) {
@@ -118,7 +116,6 @@ static uint32_t samples_per_packet(const AVCodecParameters 
*par) {
 
 static int caf_write_init(struct AVFormatContext *s)
 {
-    AVStream *const st = s->streams[0];
     AVCodecParameters *par = s->streams[0]->codecpar;
     unsigned int codec_tag = ff_codec_get_tag(ff_codec_caf_tags, 
par->codec_id);
 
@@ -138,10 +135,6 @@ static int caf_write_init(struct AVFormatContext *s)
         return AVERROR_INVALIDDATA;
     }
 
-    st->priv_data = av_mallocz(sizeof(CAFStreamContext));
-    if (!st->priv_data)
-        return AVERROR(ENOMEM);
-
     // if either block_align or frame_size are 0, we need to check that the 
output
     // is seekable. Postpone reporting init as complete until 
caf_write_header()
     if (!par->block_align || !par->frame_size)
@@ -248,33 +241,32 @@ static int caf_write_packet(AVFormatContext *s, AVPacket 
*pkt)
     AVStream *const st = s->streams[0];
 
     if (!st->codecpar->block_align || !caf->frame_size) {
-        CAFStreamContext *caf_st = st->priv_data;
         void *pkt_sizes;
         unsigned alloc_size = caf->packets + 1;
 
         if (!st->codecpar->block_align) {
-            if (UINT_MAX / sizeof(*caf_st->byte_size_buffer) < alloc_size)
+            if (UINT_MAX / sizeof(*caf->byte_size_buffer) < alloc_size)
                 return AVERROR(ERANGE);
 
-            pkt_sizes = av_fast_realloc(caf_st->byte_size_buffer,
-                                        &caf_st->byte_size_buffer_sz,
-                                        alloc_size * 
sizeof(*caf_st->byte_size_buffer));
+            pkt_sizes = av_fast_realloc(caf->byte_size_buffer,
+                                        &caf->byte_size_buffer_sz,
+                                        alloc_size * 
sizeof(*caf->byte_size_buffer));
             if (!pkt_sizes)
                 return AVERROR(ENOMEM);
-            caf_st->byte_size_buffer = pkt_sizes;
-            caf_st->byte_size_buffer[caf->packets] = pkt->size;
+            caf->byte_size_buffer = pkt_sizes;
+            caf->byte_size_buffer[caf->packets] = pkt->size;
         }
         if (!caf->frame_size) {
-            if (UINT_MAX / sizeof(*caf_st->frame_size_buffer) < alloc_size)
+            if (UINT_MAX / sizeof(*caf->frame_size_buffer) < alloc_size)
                 return AVERROR(ERANGE);
 
-            pkt_sizes = av_fast_realloc(caf_st->frame_size_buffer,
-                                        &caf_st->frame_size_buffer_sz,
-                                        alloc_size * 
sizeof(*caf_st->frame_size_buffer));
+            pkt_sizes = av_fast_realloc(caf->frame_size_buffer,
+                                        &caf->frame_size_buffer_sz,
+                                        alloc_size * 
sizeof(*caf->frame_size_buffer));
             if (!pkt_sizes)
                 return AVERROR(ENOMEM);
-            caf_st->frame_size_buffer = pkt_sizes;
-            caf_st->frame_size_buffer[caf->packets] = pkt->duration;
+            caf->frame_size_buffer = pkt_sizes;
+            caf->frame_size_buffer[caf->packets] = pkt->duration;
         }
     }
     caf->packets++;
@@ -289,7 +281,6 @@ static int caf_write_trailer(AVFormatContext *s)
     CAFContext *caf = s->priv_data;
     AVIOContext *pb = s->pb;
     AVStream *st = s->streams[0];
-    CAFStreamContext *caf_st = st->priv_data;
     AVCodecParameters *par = st->codecpar;
 
     if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
@@ -318,24 +309,24 @@ static int caf_write_trailer(AVFormatContext *s)
             for (int i = 0; i < packets; i++) {
                 if (!par->block_align) {
                     for (int j = 4; j > 0; j--) {
-                        unsigned top = caf_st->byte_size_buffer[i] >> j * 7;
+                        unsigned top = caf->byte_size_buffer[i] >> j * 7;
                         if (top) {
                             avio_w8(pb, 128 | top);
                             size++;
                         }
                     }
-                    avio_w8(pb, caf_st->byte_size_buffer[i] & 127);
+                    avio_w8(pb, caf->byte_size_buffer[i] & 127);
                     size++;
                 }
                 if (!caf->frame_size) {
                     for (int j = 4; j > 0; j--) {
-                        unsigned top = caf_st->frame_size_buffer[i] >> j * 7;
+                        unsigned top = caf->frame_size_buffer[i] >> j * 7;
                         if (top) {
                             avio_w8(pb, 128 | top);
                             size++;
                         }
                     }
-                    avio_w8(pb, caf_st->frame_size_buffer[i] & 127);
+                    avio_w8(pb, caf->frame_size_buffer[i] & 127);
                     size++;
                 }
             }
@@ -352,11 +343,10 @@ static int caf_write_trailer(AVFormatContext *s)
 
 static void caf_write_deinit(AVFormatContext *s)
 {
-    AVStream *st = s->streams[0];
-    CAFStreamContext *caf_st = st->priv_data;
+    CAFContext *caf = s->priv_data;
 
-    av_freep(&caf_st->byte_size_buffer);
-    av_freep(&caf_st->frame_size_buffer);
+    av_freep(&caf->byte_size_buffer);
+    av_freep(&caf->frame_size_buffer);
 }
 
 const FFOutputFormat ff_caf_muxer = {
-- 
2.52.0

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

Reply via email to