diff --git a/mutagen/flac.py b/mutagen/flac.py index f3b6d87e..90186229 100644 --- a/mutagen/flac.py +++ b/mutagen/flac.py @@ -732,6 +732,13 @@ def __read_metadata_block(self, fileobj): if block.code == VCFLACDict.code: if self.tags is None: self.tags = block + elif not self.tags: + # https://github.com/quodlibet/mutagen/issues/692 + # Some files have an empty first VORBIS_COMMENT block + # followed by a populated one; prefer the populated block, + # as FFmpeg and the reference implementation do. + self.metadata_blocks.remove(self.tags) + self.tags = block else: # https://github.com/quodlibet/mutagen/issues/377 # Something writes multiple and metaflac doesn't care diff --git a/tests/test_flac.py b/tests/test_flac.py index f305cef5..6721a0b1 100644 --- a/tests/test_flac.py +++ b/tests/test_flac.py @@ -339,6 +339,30 @@ def num_padding(f): self.assertEqual(num_padding(new), 1) self.assertTrue(isinstance(new.metadata_blocks[-1], Padding)) + def test_empty_vorbiscomment_before_populated(self): + # https://github.com/quodlibet/mutagen/issues/692 + # An empty VORBIS_COMMENT block before a populated one must not hide + # the tags in the populated block (FFmpeg and the reference + # implementation read the populated block in this case). + self.flac["title"] = [u"A Title"] + self.flac.save() + + # inject an empty VORBIS_COMMENT block before the populated one + f = FLAC(self.NEW) + populated = f.tags + assert populated + f.metadata_blocks.insert( + f.metadata_blocks.index(populated), VCFLACDict()) + f.save() + + f = FLAC(self.NEW) + assert f.tags + assert f["title"] == [u"A Title"] + # the empty leading block is dropped, leaving a single comment block + vc_blocks = [b for b in f.metadata_blocks + if b.code == VCFLACDict.code] + assert len(vc_blocks) == 1 + def test_increase_size_new_padding(self): self.assertEqual(self.flac.metadata_blocks[-1].length, 3060) value = u"foo" * 100