mp4: Assume udta, meta and ilst are always present.
authorAndre Noll <maan@tuebingen.mpg.de>
Sun, 22 Aug 2021 18:01:01 +0000 (20:01 +0200)
committerAndre Noll <maan@tuebingen.mpg.de>
Mon, 30 May 2022 19:37:36 +0000 (21:37 +0200)
Under normal circumstances these atoms exist or can at least be
created by other means (e.g., by running mp4tags -a foo bar.m4a).

This patch makes mp4_open_meta() fail early if at least one of the
three atoms is missing. This allows to remove the (never tested hence
probably buggy) code which creates these atoms.

error.h
mp4.c

diff --git a/error.h b/error.h
index 6e10e8ebe00e3fd7da81063c4ef3e800317fdfa7..671d0612a972ed777b55b30cadf5fd18dbd07ce6 100644 (file)
--- a/error.h
+++ b/error.h
        PARA_ERROR(MP4_META_WRITE, "mp4: could not update mp4 metadata"), \
        PARA_ERROR(MP4_OPEN, "mp4: open failed"), \
        PARA_ERROR(MP4_TRACK, "mp4: no audio track"), \
+       PARA_ERROR(MP4_MISSING_ATOM, "mp4: essential atom not found"), \
        PARA_ERROR(MPI_SCAN, "could not scan multi-precision integer"), \
        PARA_ERROR(NAME_TOO_LONG, "name too long for struct sockaddr_un"), \
        PARA_ERROR(NO_AFHI, "audio format handler info required"), \
diff --git a/mp4.c b/mp4.c
index 653e0f409560f75b476fcfa5a910639bfd7f98ec..1d8af6cb20853c33a4aff5d151eb143951bd5a90 100644 (file)
--- a/mp4.c
+++ b/mp4.c
@@ -1056,7 +1056,18 @@ int32_t mp4_num_samples(const struct mp4 *f)
 
 int mp4_open_meta(const struct mp4_callback *cb, struct mp4 **result)
 {
-       return open_file(cb, true, result);
+       struct mp4 *f;
+       int ret = open_file(cb, true, &f);
+
+       if (ret < 0)
+               return ret;
+       if (f->udta_size == 0 || f->meta_size == 0 || f->ilst_size == 0) {
+               mp4_close(f);
+               *result = NULL;
+               return -E_MP4_MISSING_ATOM;
+       }
+       *result = f;
+       return 1;
 }
 
 /**
@@ -1167,75 +1178,6 @@ static void *create_ilst(const struct mp4_metadata *meta, uint32_t *out_size)
        return membuffer_detach(buf);
 }
 
-static void membuffer_write_atom(struct membuffer *buf, const char *name, unsigned size,
-                         const void *data)
-{
-       membuffer_write_int32(buf, size + 8);
-       membuffer_write_atom_name(buf, name);
-       membuffer_write(buf, data, size);
-}
-
-static void *membuffer_get_ptr(const struct membuffer *buf)
-{
-       return buf->data;
-}
-
-static bool membuffer_transfer_from_file(struct membuffer *buf, struct mp4 *src,
-               unsigned bytes)
-{
-       unsigned oldsize = membuffer_get_size(buf);
-       char *bufptr;
-
-       membuffer_write(buf, 0, bytes);
-       bufptr = membuffer_get_ptr(buf);
-       if (read_data(src, bufptr + oldsize, bytes) != 1) {
-               free(buf->data);
-               free(buf);
-               return false;
-       }
-       return true;
-}
-
-static uint32_t create_meta(const struct mp4_metadata *meta, void **out_buffer,
-               uint32_t * out_size)
-{
-       struct membuffer *buf;
-       uint32_t ilst_size;
-       void *ilst_buffer;
-
-       ilst_buffer = create_ilst(meta, &ilst_size);
-
-       buf = membuffer_create();
-       membuffer_write_int32(buf, 0);
-       membuffer_write_atom(buf, "ilst", ilst_size, ilst_buffer);
-       free(ilst_buffer);
-
-       *out_size = membuffer_get_size(buf);
-       *out_buffer = membuffer_detach(buf);
-       return 1;
-}
-
-static uint32_t create_udta(const struct mp4_metadata *meta, void **out_buffer,
-uint32_t * out_size)
-{
-       struct membuffer *buf;
-       uint32_t meta_size;
-       void *meta_buffer;
-
-       if (!create_meta(meta, &meta_buffer, &meta_size))
-               return 0;
-
-       buf = membuffer_create();
-
-       membuffer_write_atom(buf, "meta", meta_size, meta_buffer);
-
-       free(meta_buffer);
-
-       *out_size = membuffer_get_size(buf);
-       *out_buffer = membuffer_detach(buf);
-       return 1;
-}
-
 static uint32_t fix_byte_order_32(uint32_t src)
 {
        return read_u32_be(&src);
@@ -1252,56 +1194,6 @@ static void *modify_moov(struct mp4 *f, uint32_t *out_size)
        int32_t size_delta;
        uint32_t tmp;
 
-       if (f->udta_size == 0) {
-               struct membuffer *buf;
-               void *new_udta_buffer;
-               uint32_t new_udta_size;
-               if (!create_udta(&f->meta, &new_udta_buffer, &new_udta_size))
-                       return NULL;
-
-               buf = membuffer_create();
-               set_position(f, total_base);
-               if (!membuffer_transfer_from_file(buf, f, total_size)) {
-                       free(new_udta_buffer);
-                       return NULL;
-               }
-               membuffer_write_atom(buf, "udta", new_udta_size,
-                       new_udta_buffer);
-
-               free(new_udta_buffer);
-
-               *out_size = membuffer_get_size(buf);
-               return membuffer_detach(buf);
-       }
-       if (f->meta_size == 0 || f->ilst_size == 0) {
-               struct membuffer *buf;
-               void *new_meta_buffer;
-               uint32_t new_meta_size;
-
-               if (!create_meta(&f->meta, &new_meta_buffer, &new_meta_size))
-                       return NULL;
-
-               buf = membuffer_create();
-               set_position(f, total_base);
-               if (!membuffer_transfer_from_file(buf, f,
-                               f->udta_offset - total_base)) {
-                       free(new_meta_buffer);
-                       return NULL;
-               }
-
-               membuffer_write_int32(buf, f->udta_size + 8 + new_meta_size);
-               membuffer_write_atom_name(buf, "udta");
-               if (!membuffer_transfer_from_file(buf, f, f->udta_size)) {
-                       free(new_meta_buffer);
-                       return NULL;
-               }
-               membuffer_write_atom(buf, "meta", new_meta_size,
-                       new_meta_buffer);
-               free(new_meta_buffer);
-
-               *out_size = membuffer_get_size(buf);
-               return membuffer_detach(buf);
-       }
        new_ilst_buffer = create_ilst(&f->meta, &new_ilst_size);
        size_delta = new_ilst_size - (f->ilst_size - 8);
        *out_size = total_size + size_delta;