From 9f35e220ffbba21c88356eb2bbfa3679ede93793 Mon Sep 17 00:00:00 2001 From: Ackanir Date: Mon, 17 Aug 2026 14:36:53 +0200 Subject: [PATCH] avformat/movenc: fix crash when flushing a fragment with no data mov_flush_fragment() calls ffio_reset_dyn_buf() on mov->mdat_buf when writing the initial moov. That buffer is allocated lazily on the first packet, so it is still NULL when the trailer is written before anything was muxed, and ffio_reset_dyn_buf() dereferences it. 627da1111c9d replaced ffio_free_dyn_buf(), which tolerates NULL, with ffio_reset_dyn_buf(), which does not, turning this case into a crash. This affects every fragmented mode that defers the initial moov to the first flush. Skip the block entirely when the buffer was never opened. Nothing references the empty mdat it would otherwise write, as no samples were muxed. Reproduced with: ffmpeg -f lavfi -i color=s=64x64 -frames:v 0 -movflags +frag_keyframe out.mp4 Fixes: 627da1111c9d ("libavformat/movenc: Uses dynamic buffers for fragmented chunks") Signed-off-by: Ackanir --- libavformat/movenc.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/libavformat/movenc.c b/libavformat/movenc.c index 14504d0947..4c7868c5f8 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -6804,11 +6804,13 @@ static int mov_flush_fragment(AVFormatContext *s, int force) return 0; } - buf_size = avio_get_dyn_buf(mov->mdat_buf, &buf); - avio_wb32(s->pb, buf_size + 8); - ffio_wfourcc(s->pb, "mdat"); - avio_write(s->pb, buf, buf_size); - ffio_reset_dyn_buf(mov->mdat_buf); + if (mov->mdat_buf) { + buf_size = avio_get_dyn_buf(mov->mdat_buf, &buf); + avio_wb32(s->pb, buf_size + 8); + ffio_wfourcc(s->pb, "mdat"); + avio_write(s->pb, buf, buf_size); + ffio_reset_dyn_buf(mov->mdat_buf); + } if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX) mov->reserved_header_pos = avio_tell(s->pb);