PR #25175 opened by Marti2203 URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25175 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25175.patch
Follow-up to #25169, from its review. The marker Entry Length in `asf_write_markers()` is a 16-bit field covering 12 fixed bytes plus the UTF-16 description, so a chapter title over 32760 characters wraps it while the full description is written: a 33000-character title gives an Entry Length of 478 instead of 66014 (read from the Marker Object directly; FFmpeg's own reader uses the description count and truncates titles, so ffprobe does not show it). Readers that rely on Entry Length misparse the following markers. With the patch, titles are checked before the Marker Object is written and the muxer fails with "Chapter N title is too long for ASF". A 32760-character title (Entry Length 65534) and ordinary multi-chapter files are written as before. The description length is measured on the bytes actually written, as the writer does, so titles with invalid UTF-8 are unaffected (their Entry Length is already consistent). FATE `lavf-asf` and `seek-lavf-asf` pass. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01PJjAkXVedLvPoWWc6fokZ3 From c530eb80c7a9ded63b4897bf2b5bd38f1cf313fc Mon Sep 17 00:00:00 2001 From: Martin Mirchev <[email protected]> Date: Sun, 18 Oct 2026 17:23:01 +0800 Subject: [PATCH] avformat/asfenc: reject chapter titles too long for the marker entry The marker Entry Length is a 16-bit field covering 12 fixed bytes and the UTF-16 description, so a chapter title over 32760 characters wrapped it (e.g. 478 instead of 66014 for a 33000-character title). Readers that rely on Entry Length then misparse the following markers. Check the titles before writing the Marker Object and fail instead. Found while reviewing the metadata length fix for ASF. Signed-off-by: Martin Mirchev <[email protected]> --- libavformat/asfenc.c | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/libavformat/asfenc.c b/libavformat/asfenc.c index 59638e7b22..4847a6b42c 100644 --- a/libavformat/asfenc.c +++ b/libavformat/asfenc.c @@ -308,12 +308,31 @@ static int32_t get_send_time(ASFContext *asf, int64_t pres_time, uint64_t *offse return send_time / 10000; } -static void asf_write_markers(AVFormatContext *s, AVIOContext *dyn_buf) +static int asf_write_markers(AVFormatContext *s, AVIOContext *dyn_buf) { ASFContext *asf = s->priv_data; AVIOContext *pb = s->pb; AVRational scale = {1, 10000000}; - int64_t hpos = put_header(pb, &ff_asf_marker_header); + int64_t hpos; + + /* the 16-bit entry length covers 12 fixed bytes and the description */ + for (unsigned i = 0; i < s->nb_chapters; i++) { + const AVDictionaryEntry *t = av_dict_get(s->chapters[i]->metadata, + "title", NULL, 0); + if (t) { + uint8_t *buf; + int len; + avio_put_str16le(dyn_buf, t->value); + len = avio_get_dyn_buf(dyn_buf, &buf); + ffio_reset_dyn_buf(dyn_buf); + if (len > UINT16_MAX - 12) { + av_log(s, AV_LOG_ERROR, "Chapter %u title is too long for ASF\n", i); + return AVERROR(EINVAL); + } + } + } + + hpos = put_header(pb, &ff_asf_marker_header); ff_put_guid(pb, &ff_asf_reserved_4);// ASF spec mandates this reserved value avio_wl32(pb, s->nb_chapters); // markers count @@ -344,6 +363,7 @@ static void asf_write_markers(AVFormatContext *s, AVIOContext *dyn_buf) } } end_header(pb, hpos); + return 0; } /* write the header (used two times if non streamed) */ @@ -573,7 +593,8 @@ static int asf_write_header1(AVFormatContext *s, int64_t file_size, } /* chapters using ASF markers */ if (!asf->is_streamed && s->nb_chapters) { - asf_write_markers(s, dyn_buf); + if ((ret = asf_write_markers(s, dyn_buf)) < 0) + goto fail; } /* stream headers */ for (unsigned n = 0; n < s->nb_streams; n++) { -- 2.54.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
