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

Use temporary key state while parsing a meta box and restore the previous state 
afterwards, preventing key tables from leaking across separate or nested 
metadata boxes.

Fixes issue #24106.



>From d12997c2cbaa02f46795b43ea39d8a1342d98131 Mon Sep 17 00:00:00 2001
From: jiangjie <[email protected]>
Date: Wed, 12 Aug 2026 13:01:00 +0800
Subject: [PATCH] avformat/mov: scope metadata keys to each meta box

Use temporary key state while parsing a meta box and restore the previous state 
afterwards, preventing key tables from leaking across separate or nested 
metadata boxes.

Fixes issue #24106.
---
 libavformat/mov.c | 43 +++++++++++++++++++++++++++++++++----------
 1 file changed, 33 insertions(+), 10 deletions(-)

diff --git a/libavformat/mov.c b/libavformat/mov.c
index 5a66d572ee..0b597b599c 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -5763,6 +5763,16 @@ static int mov_read_keys(MOVContext *c, AVIOContext *pb, 
MOVAtom atom)
     return 0;
 }
 
+static void mov_free_meta_keys(MOVContext *c)
+{
+    if (c->meta_keys) {
+        for (unsigned i = 1; i < c->meta_keys_count; i++)
+            av_freep(&c->meta_keys[i]);
+        av_freep(&c->meta_keys);
+    }
+    c->meta_keys_count = 0;
+}
+
 static int mov_read_custom(MOVContext *c, AVIOContext *pb, MOVAtom atom)
 {
     int64_t end = av_sat_add64(avio_tell(pb), atom.size);
@@ -5924,19 +5934,37 @@ fail:
 
 static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
 {
+    char **meta_keys = c->meta_keys;
+    unsigned meta_keys_count = c->meta_keys_count;
+    int found_hdlr_mdta = c->found_hdlr_mdta;
+    int ret = 0;
+
+    c->meta_keys = NULL;
+    c->meta_keys_count = 0;
+    c->found_hdlr_mdta = 0;
+
     while (atom.size > 8) {
         uint32_t tag;
-        if (avio_feof(pb))
-            return AVERROR_EOF;
+        if (avio_feof(pb)) {
+            ret = AVERROR_EOF;
+            break;
+        }
         tag = avio_rl32(pb);
         atom.size -= 4;
         if (tag == MKTAG('h','d','l','r')) {
             avio_seek(pb, -8, SEEK_CUR);
             atom.size += 8;
-            return mov_read_default(c, pb, atom);
+            ret = mov_read_default(c, pb, atom);
+            break;
         }
     }
-    return 0;
+
+    mov_free_meta_keys(c);
+    c->meta_keys = meta_keys;
+    c->meta_keys_count = meta_keys_count;
+    c->found_hdlr_mdta = found_hdlr_mdta;
+
+    return ret;
 }
 
 // return 1 when matrix is identity, 0 otherwise
@@ -10610,12 +10638,7 @@ static int mov_read_close(AVFormatContext *s)
     avformat_free_context(mov->dv_fctx);
     mov->dv_fctx = NULL;
 
-    if (mov->meta_keys) {
-        for (i = 1; i < mov->meta_keys_count; i++) {
-            av_freep(&mov->meta_keys[i]);
-        }
-        av_freep(&mov->meta_keys);
-    }
+    mov_free_meta_keys(mov);
 
     av_freep(&mov->trex_data);
     av_freep(&mov->bitrates);
-- 
2.52.0

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

Reply via email to