From 348b7a06f3fea50112bf939a6c729ce226b41cd9 Mon Sep 17 00:00:00 2001 From: sezanzeb Date: Sun, 13 Aug 2023 12:36:59 +0200 Subject: [PATCH 1/2] Recurse m4a atoms to search for ilst --- mutagen/mp4/__init__.py | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/mutagen/mp4/__init__.py b/mutagen/mp4/__init__.py index 9e1757ec..f9203517 100644 --- a/mutagen/mp4/__init__.py +++ b/mutagen/mp4/__init__.py @@ -340,17 +340,27 @@ def __init__(self, *args, **kwargs): if args or kwargs: self.load(*args, **kwargs) - def load(self, atoms, fileobj): - try: - path = atoms.path(b"moov", b"udta", b"meta", b"ilst") - except KeyError as key: - raise MP4MetadataError(key) - - free = _find_padding(path) - self._padding = free.datalength if free is not None else 0 + def load(self, atoms: Atoms, fileobj): + for atom in atoms.atoms: + if atom.children is not None: + self._recurse_atom(atom, fileobj) + + def _recurse_atom(self, parent: Atom, fileobj): + """Recursively search for an ilst atom to read metadata from. + + Recursing helps if the mp4/m4a container didn't store metadata correctly, + which is usually expected at moov.udta.meta.ilst""" + if parent.name != b"ilst": + for atom in parent.children: + if parent.name == b"meta" and atom.name == b"ilst": + free = _find_padding([parent, atom]) + self._padding = free.datalength if free is not None else 0 + + if atom.children is not None and atom.name != 'ilst': + self._recurse_atom(atom, fileobj) + return - ilst = path[-1] - for atom in ilst.children: + for atom in parent.children: ok, data = atom.read(fileobj) if not ok: raise MP4MetadataError("Not enough data") From 638751c5a5773a35e6482ba7df5b9c707566eb0b Mon Sep 17 00:00:00 2001 From: sezanzeb Date: Sun, 13 Aug 2023 12:54:23 +0200 Subject: [PATCH 2/2] return early when children are None --- mutagen/mp4/__init__.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mutagen/mp4/__init__.py b/mutagen/mp4/__init__.py index f9203517..e051e751 100644 --- a/mutagen/mp4/__init__.py +++ b/mutagen/mp4/__init__.py @@ -350,6 +350,9 @@ def _recurse_atom(self, parent: Atom, fileobj): Recursing helps if the mp4/m4a container didn't store metadata correctly, which is usually expected at moov.udta.meta.ilst""" + if parent.children is None: + return + if parent.name != b"ilst": for atom in parent.children: if parent.name == b"meta" and atom.name == b"ilst":