]> git.tuebingen.mpg.de Git - paraslash.git/blobdiff - mp4.c
mp4: Introduce min_body_size() helper.
[paraslash.git] / mp4.c
diff --git a/mp4.c b/mp4.c
index b2a4795d924d4e8e03fccd7c5b29b8cfa3225b76..e66fcea2e6ad79adb0e2e09071df20bf853f3bdb 100644 (file)
--- a/mp4.c
+++ b/mp4.c
@@ -952,7 +952,30 @@ static int32_t mp4ff_set_metadata_name(const uint8_t atom_type, char **name)
        return 0;
 }
 
-static int32_t mp4ff_parse_tag(mp4ff_t * f, const uint8_t parent_atom_type,
+static uint32_t min_body_size(const uint8_t atom_type)
+{
+       switch(atom_type) {
+       case ATOM_GENRE2:
+       case ATOM_TEMPO:
+               return 10;
+       case ATOM_TRACK:
+               return sizeof (char) /* version */
+                       + sizeof(uint8_t) * 3 /* flags */
+                       + sizeof(uint32_t) /* reserved */
+                       + sizeof(uint16_t) /* leading uint16_t */
+                       + sizeof(uint16_t) /* track */
+                       + sizeof(uint16_t); /* totaltracks */
+       case ATOM_DISC:
+               return sizeof (char) /* version */
+                       + sizeof(uint8_t) * 3 /* flags */
+                       + sizeof(uint32_t) /* reserved */
+                       + sizeof(uint16_t) /* disc */
+                       + sizeof(uint16_t); /* totaldiscs */
+       default: assert(false);
+       }
+}
+
+static int32_t mp4ff_parse_tag(mp4ff_t * f, const uint8_t parent,
                const int32_t size)
 {
        uint8_t atom_type;
@@ -977,7 +1000,7 @@ static int32_t mp4ff_parse_tag(mp4ff_t * f, const uint8_t parent_atom_type,
                        mp4ff_read_char(f);     /* version */
                        mp4ff_read_int24(f);    /* flags */
                        free(name);
-                       name = mp4ff_read_string(f, (uint32_t) (subsize - (header_size + 4)));
+                       name = mp4ff_read_string(f, subsize - (header_size + 4));
                        continue;
                }
                if (atom_type != ATOM_DATA)
@@ -987,56 +1010,53 @@ static int32_t mp4ff_parse_tag(mp4ff_t * f, const uint8_t parent_atom_type,
                mp4ff_read_int32(f);    /* reserved */
 
                /* some need special attention */
-               if (parent_atom_type == ATOM_GENRE2 || parent_atom_type == ATOM_TEMPO) {
-                       if (subsize - header_size >= 8 + 2) {
-                               uint16_t val = mp4ff_read_int16(f);
-
-                               if (parent_atom_type == ATOM_TEMPO) {
-                                       char temp[16];
-                                       sprintf(temp, "%.5u BPM", val);
-                                       mp4ff_tag_add_field(&(f-> tags), "tempo", temp, -1);
-                               } else {
-                                       const char *temp = mp4ff_meta_index_to_genre(val);
-                                       if (temp)
-                                               mp4ff_tag_add_field (&(f->tags), "genre", temp, -1);
-                               }
-                               done = 1;
+               if (parent == ATOM_GENRE2 || parent == ATOM_TEMPO) {
+                       uint16_t val;
+                       if (subsize - header_size < min_body_size(parent))
+                               continue;
+                       val = mp4ff_read_int16(f);
+                       if (parent == ATOM_TEMPO) {
+                               char temp[16];
+                               sprintf(temp, "%.5u BPM", val);
+                               mp4ff_tag_add_field(&(f-> tags), "tempo",
+                                       temp, -1);
+                       } else {
+                               const char *tmp = mp4ff_meta_index_to_genre(val);
+                               if (tmp)
+                                       mp4ff_tag_add_field (&(f->tags),
+                                               "genre", tmp, -1);
                        }
-               } else if (parent_atom_type == ATOM_TRACK || parent_atom_type == ATOM_DISC) {
-                       if (subsize - header_size >= (sizeof (char) + sizeof (uint8_t) * 3 + sizeof (uint32_t) +        /* version + flags + reserved */
-                                                                +(parent_atom_type == ATOM_TRACK ? sizeof (uint16_t) : 0)      /* leading uint16_t if ATOM_TRACK */
-                                                                +sizeof (uint16_t)     /* track / disc */
-                                                                +sizeof (uint16_t))    /* totaltracks / totaldiscs */) {
-                               uint16_t index, total;
-                               char temp[32];
+                       done = 1;
+               } else if (parent == ATOM_TRACK || parent == ATOM_DISC) {
+                       uint16_t index, total;
+                       char temp[32];
+                       if (subsize - header_size < min_body_size(parent))
+                               continue;
+                       mp4ff_read_int16(f);
+                       index = mp4ff_read_int16(f);
+                       total = mp4ff_read_int16(f);
+                       if (parent == ATOM_TRACK)
                                mp4ff_read_int16(f);
-                               index = mp4ff_read_int16(f);
-                               total = mp4ff_read_int16(f);
-                               if (parent_atom_type == ATOM_TRACK)
-                                       mp4ff_read_int16(f);
-
-                               sprintf(temp, "%d", index);
-                               mp4ff_tag_add_field(&(f->tags), parent_atom_type == ATOM_TRACK ?
-                                       "track" : "disc", temp, -1);
-                               if (total > 0) {
-                                       sprintf(temp, "%d",
-                                               total);
-                                       mp4ff_tag_add_field(& (f-> tags),
-                                               parent_atom_type == ATOM_TRACK?
-                                               "totaltracks" : "totaldiscs", temp, -1);
-                               }
-                               done = 1;
+                       sprintf(temp, "%d", index);
+                       mp4ff_tag_add_field(&(f->tags), parent == ATOM_TRACK?
+                               "track" : "disc", temp, -1);
+                       if (total > 0) {
+                               sprintf(temp, "%d", total);
+                               mp4ff_tag_add_field(& (f-> tags),
+                                       parent == ATOM_TRACK?
+                                       "totaltracks" : "totaldiscs", temp, -1);
                        }
+                       done = 1;
                } else {
                        free(data);
-                       data = mp4ff_read_string(f, (uint32_t) (subsize - (header_size + 8)));
-                       len = (uint32_t) (subsize - (header_size + 8));
+                       data = mp4ff_read_string(f, subsize - (header_size + 8));
+                       len = subsize - (header_size + 8);
                }
        }
        if (data) {
                if (!done) {
                        if (name == NULL)
-                               mp4ff_set_metadata_name(parent_atom_type, &name);
+                               mp4ff_set_metadata_name(parent , &name);
                        if (name)
                                mp4ff_tag_add_field(&(f->tags), name, data, len);
                }