From 30fcea984715a12b63aab776fb3080ac1851e43a Mon Sep 17 00:00:00 2001 From: Andre Noll Date: Sun, 22 Aug 2021 20:01:01 +0200 Subject: [PATCH] mp4: Assume udta, meta and ilst are always present. 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 | 1 + mp4.c | 132 ++++++-------------------------------------------------- 2 files changed, 13 insertions(+), 120 deletions(-) diff --git a/error.h b/error.h index 6e10e8eb..671d0612 100644 --- a/error.h +++ b/error.h @@ -144,6 +144,7 @@ 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 653e0f40..1d8af6cb 100644 --- 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; -- 2.39.2