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

Fixes issue #24106

Each meta box has its own keys table. Keep the parsing state local to the 
current box so values from separate metadata containers are not resolved 
through an earlier table.

# Summary of changes

Briefly describe what this PR does and why.

<!--
If this PR requires new FATE test samples, attach them to the PR and
list their target paths below (relative to the fate-suite root).

Attached filenames must match the sample's filename:

```fate-samples
# e.g. vorbis/new-sample.ogg
```
-->



>From 8c9ea618a6658f3f6281a9463c2c8dc217da5c9c Mon Sep 17 00:00:00 2001
From: jiangjie <[email protected]>
Date: Thu, 13 Aug 2026 11:06:02 +0800
Subject: [PATCH] avformat/mov: scope metadata keys to each meta box

Fixes issue #24106

Each meta box has its own keys table. Keep the parsing state local to the 
current box so values from separate metadata containers are not resolved 
through an earlier table.
---
 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