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]

Reply via email to