Commit 513df1ccdd for ffmpeg

commit 513df1ccdd8266cf32ab68403f7065718f91bf7b
Author: James Almer <jamrial@gmail.com>
Date:   Sun Oct 11 21:06:54 2026 -0300

    avformat/mov: split off ipco and ipma box parsing to their own functions

    Signed-off-by: James Almer <jamrial@gmail.com>

diff --git a/libavformat/mov.c b/libavformat/mov.c
index 5660d2a07a..f7c12922d9 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -10081,86 +10081,68 @@ static int mov_read_imir(MOVContext *c, AVIOContext *pb, MOVAtom atom)
     return 0;
 }

-static int mov_read_iprp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
-{
-    typedef struct MOVAtoms {
-        FFIOContext b;
-        uint32_t type;
-        int64_t  size;
-        uint8_t *data;
-    } MOVAtoms;
-    MOVAtoms *atoms = NULL;
-    MOVAtom a;
-    unsigned count;
-    int nb_atoms = 0;
-    int version, flags;
-    int ret;
-
-    a.size = avio_rb32(pb);
-    a.type = avio_rl32(pb);
+typedef struct MOVAtomExt {
+    uint32_t type;
+    int64_t size;
+    uint8_t *data;
+} MOVAtomExt;

-    if (a.size < 8 || a.size > atom.size || a.type != MKTAG('i','p','c','o'))
-        return AVERROR_INVALIDDATA;
+static int mov_read_ipco(MOVContext *c, AVIOContext *pb, MOVAtom atom,
+                         MOVAtomExt **atoms, int *nb_atoms)
+{
+    while (atom.size >= 8) {
+        MOVAtomExt *ref = av_dynarray2_add((void**)atoms, nb_atoms, sizeof(MOVAtomExt), NULL);
+        if (!ref)
+            return AVERROR(ENOMEM);

-    atom.size -= a.size;
-    a.size -= 8;
-    while (a.size >= 8) {
-        MOVAtoms *ref = av_dynarray2_add((void**)&atoms, &nb_atoms, sizeof(MOVAtoms), NULL);
-        if (!ref) {
-            ret = AVERROR(ENOMEM);
-            goto fail;
-        }
         ref->data = NULL;
         ref->size = avio_rb32(pb);
         ref->type = avio_rl32(pb);
-        if (ref->size > a.size || ref->size < 8)
+        if (ref->size > atom.size || ref->size < 8)
             break;
         ref->data = av_malloc(ref->size);
-        if (!ref->data) {
-            ret = AVERROR_INVALIDDATA;
-            goto fail;
-        }
-        av_log(c->fc, AV_LOG_TRACE, "ipco: index %d, box type %s\n", nb_atoms, av_fourcc2str(ref->type));
+        if (!ref->data)
+            return AVERROR_INVALIDDATA;
+
+        av_log(c->fc, AV_LOG_TRACE, "ipco: index %d, box type %s\n", *nb_atoms,
+               av_fourcc2str(ref->type));
         AV_WB32(ref->data, ref->size);
         AV_WL32(ref->data + 4, ref->type);
         if (avio_read(pb, ref->data + 8, ref->size - 8) != ref->size - 8) {
-            ret = AVERROR_INVALIDDATA;
-            goto fail;
+            return AVERROR_INVALIDDATA;
         }
-        ffio_init_read_context(&ref->b, ref->data, ref->size);
-        a.size -= ref->size;
+        atom.size -= ref->size;
     }

-    if (a.size) {
-        ret = AVERROR_INVALIDDATA;
-        goto fail;
-    }
+    if (atom.size)
+        return AVERROR_INVALIDDATA;

-    a.size = avio_rb32(pb);
-    a.type = avio_rl32(pb);
+    return 0;
+}

-    if (a.size < 16 || a.size > atom.size || a.type != MKTAG('i','p','m','a')) {
-        ret = AVERROR_INVALIDDATA;
-        goto fail;
-    }
+static int mov_read_ipma(MOVContext *c, AVIOContext *pb, MOVAtom atom,
+                         MOVAtomExt *atoms, int nb_atoms)
+{
+    unsigned count;
+    int version, flags;
+    int ret;

     version = avio_r8(pb);
     flags   = avio_rb24(pb);
     count   = avio_rb32(pb);
-    a.size -= 16;
+    atom.size -= 8;

     for (int i = 0; i < count; i++) {
         int item_id = version ? avio_rb32(pb) : avio_rb16(pb);
         int assoc_count = avio_r8(pb);

-        a.size -= (version ? 5 : 3) + assoc_count * (1 + (flags & 1));
-        if (avio_feof(pb) || a.size < 0) {
-            ret = AVERROR_INVALIDDATA;
-            goto fail;
-        }
+        atom.size -= (version ? 5 : 3) + assoc_count * (1 + (flags & 1));
+        if (avio_feof(pb) || atom.size < 0)
+            return AVERROR_INVALIDDATA;

         for (int j = 0; j < assoc_count; j++) {
-            MOVAtoms *ref;
+            FFIOContext b;
+            MOVAtomExt *ref;
             int index = avio_r8(pb) & 0x7f;
             if (flags & 1) {
                 index <<= 8;
@@ -10169,8 +10151,7 @@ static int mov_read_iprp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
             if (!index)
                 continue;
             if (index > nb_atoms) {
-                ret = AVERROR_INVALIDDATA;
-                goto fail;
+                return AVERROR_INVALIDDATA;
             }
             ref = &atoms[--index];

@@ -10179,15 +10160,55 @@ static int mov_read_iprp(MOVContext *c, AVIOContext *pb, MOVAtom atom)

             c->cur_item_id = item_id;

-            ret = mov_read_default(c, &ref->b.pub,
+            ffio_init_read_context(&b, ref->data, ref->size);
+            ret = mov_read_default(c, &b.pub,
                                    (MOVAtom) { .size = ref->size,
                                                .type = MKTAG('i','p','c','o') });
             if (ret < 0)
-                goto fail;
-            ffio_init_read_context(&ref->b, ref->data, ref->size);
+                return ret;
         }
     }

+    if (atom.size)
+        return AVERROR_INVALIDDATA;
+
+    return 0;
+}
+
+static int mov_read_iprp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
+{
+    MOVAtomExt *atoms = NULL;
+    MOVAtom a;
+    int nb_atoms = 0;
+    int ret;
+
+    a.size = avio_rb32(pb);
+    a.type = avio_rl32(pb);
+
+    if (a.size <= 8 || a.size > atom.size || a.type != MKTAG('i','p','c','o'))
+        return AVERROR_INVALIDDATA;
+
+    atom.size -= a.size;
+    a.size -= 8;
+
+    ret = mov_read_ipco(c, pb, a, &atoms, &nb_atoms);
+    if (ret < 0)
+        goto fail;
+
+    a.size = avio_rb32(pb);
+    a.type = avio_rl32(pb);
+
+    if (a.size <= 8 || a.size > atom.size || a.type != MKTAG('i','p','m','a')) {
+        ret = AVERROR_INVALIDDATA;
+        goto fail;
+    }
+
+    a.size -= 8;
+
+    ret = mov_read_ipma(c, pb, a, atoms, nb_atoms);
+    if (ret < 0)
+        goto fail;
+
     ret = 0;
 fail:
     c->cur_item_id = -1;