From f567825065e16a2e838630dcc42adc6817cef2a7 Mon Sep 17 00:00:00 2001 From: Elaine Chen Date: Fri, 10 Apr 2026 17:19:11 -0400 Subject: [PATCH 1/8] Raise FileTypeError for WAVE_FORMAT_MPEGLAYER3 WAV files WAV files containing an MP3 stream (wFormatTag=0x0055) are silently mishandled by mutagen, returning incorrect duration, bitrate, and format metadata. Detect this subtype via the audio_format attribute and raise FileTypeError with a clear message instead. Adds a test fixture and regression test. Ref: beetbox/beets#6455 --- mediafile/__init__.py | 4 ++++ test/rsrc/mpeglayer3.wav | Bin 0 -> 40438 bytes test/test_mediafile_edge.py | 6 ++++++ 3 files changed, 10 insertions(+) create mode 100644 test/rsrc/mpeglayer3.wav diff --git a/mediafile/__init__.py b/mediafile/__init__.py index 7b2cb8a..f88b436 100644 --- a/mediafile/__init__.py +++ b/mediafile/__init__.py @@ -187,6 +187,10 @@ def __init__(self, filething, id3v23=False): elif type(self.mgfile).__name__ == "DSF": self.type = "dsf" elif type(self.mgfile).__name__ == "WAVE": + # WAVE_FORMAT_MPEGLAYER3 (0x0055) : MP3 stream in a WAV container + # mutagen cannot tag it correctly. + if getattr(self.mgfile.info, "audio_format", 1) == 0x55: + raise FileTypeError(self.filename, "WAVE_FORMAT_MPEGLAYER3") self.type = "wav" else: raise FileTypeError(self.filename, type(self.mgfile).__name__) diff --git a/test/rsrc/mpeglayer3.wav b/test/rsrc/mpeglayer3.wav new file mode 100644 index 0000000000000000000000000000000000000000..89f933f01315b69ae53b90e7c1a4c9b7ed1a6094 GIT binary patch literal 40438 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 literal 0 HcmV?d00001 diff --git a/test/test_mediafile_edge.py b/test/test_mediafile_edge.py index bf93bc7..570f6fe 100644 --- a/test/test_mediafile_edge.py +++ b/test/test_mediafile_edge.py @@ -173,6 +173,12 @@ def test_broken_symlink(self): finally: os.unlink(fn) + def test_mpeglayer3_wav_raises_filetypeerror(self): + # WAV files with WAVE_FORMAT_MPEGLAYER3 (OxOO55) contain a MP3 stream + # and cannot be tagged correctly + fn = os.path.join(_common.RSRC, b"mpeglayer3.wav") + self.assertRaises(mediafile.FileTypeError, mediafile.MediaFile, fn) + class SideEffectsTest(unittest.TestCase): def setUp(self): From a6cd2fbbbde051a8a0c73706db97267fa9ec7002 Mon Sep 17 00:00:00 2001 From: Elaine Chen Date: Fri, 10 Apr 2026 17:28:52 -0400 Subject: [PATCH 2/8] Add changelog entry for WAVE_FORMAT_MPEGLAYER3 fix --- docs/changelog.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/changelog.rst b/docs/changelog.rst index 14ddee0..22a17f6 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -3,6 +3,9 @@ Changelog Upcoming -------- +- Raise ``FileTypeError`` for WAV files containing an MP3 stream + (``WAVE_FORMAT_MPEGLAYER3``, ``wFormatTag=0x0055``), which mutagen cannot tag + correctly, instead of returning the wrong metadata. v0.16.0 ------- From d108a218e675bae5979f93e8f4c8cc758da0f519 Mon Sep 17 00:00:00 2001 From: Elaine Chen Date: Sat, 11 Apr 2026 13:48:22 -0400 Subject: [PATCH 3/8] Extend WAV format blacklist to include ADPCM, A-law, and mu-law In addition to WAVE_FORMAT_MPEGLAYER3 (0x0055), also reject WAVE_FORMAT_ADPCM (0x0002), WAVE_FORMAT_ALAW (0x0006), and WAVE_FORMAT_MULAW (0x0007). --- mediafile/__init__.py | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/mediafile/__init__.py b/mediafile/__init__.py index f88b436..71b1b98 100644 --- a/mediafile/__init__.py +++ b/mediafile/__init__.py @@ -187,10 +187,19 @@ def __init__(self, filething, id3v23=False): elif type(self.mgfile).__name__ == "DSF": self.type = "dsf" elif type(self.mgfile).__name__ == "WAVE": - # WAVE_FORMAT_MPEGLAYER3 (0x0055) : MP3 stream in a WAV container - # mutagen cannot tag it correctly. - if getattr(self.mgfile.info, "audio_format", 1) == 0x55: - raise FileTypeError(self.filename, "WAVE_FORMAT_MPEGLAYER3") + # WAV files can contain non-PCM audio streams that mutagen + # cannot tag correctly. Rejects them with a clear error. + _unsupported_wav_formats = { + 0x0002: "WAVE_FORMAT_ADPCM", + 0x0006: "WAVE_FORMAT_ALAW", + 0x0007: "WAVE_FORMAT_MULAW", + 0x0055: "WAVE_FORMAT_MPEGLAYER3", + } + audio_fmt = getattr(self.mgfile.info, "audio_format", 0x0001) + if audio_fmt in _unsupported_wav_formats: + raise FileTypeError( + self.filename, _unsupported_wav_formats[audio_fmt] + ) self.type = "wav" else: raise FileTypeError(self.filename, type(self.mgfile).__name__) From 968690f83244d2e9a3981007336f578824d727f2 Mon Sep 17 00:00:00 2001 From: Elaine Chen Date: Sat, 11 Apr 2026 13:56:20 -0400 Subject: [PATCH 4/8] Updated changelog to reflect the expanded WAV format blacklist --- docs/changelog.rst | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/changelog.rst b/docs/changelog.rst index 22a17f6..1596573 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -3,9 +3,10 @@ Changelog Upcoming -------- -- Raise ``FileTypeError`` for WAV files containing an MP3 stream - (``WAVE_FORMAT_MPEGLAYER3``, ``wFormatTag=0x0055``), which mutagen cannot tag - correctly, instead of returning the wrong metadata. +- Raise ``FileTypeError`` for WAV files containing non-PCM audio streams + that mutagen cannot tag correctly, including ``WAVE_FORMAT_MPEGLAYER3`` + (0x0055), ``WAVE_FORMAT_ADPCM`` (0x0002), ``WAVE_FORMAT_ALAW`` (0x0006), + and ``WAVE_FORMAT_MULAW`` (0x0007). v0.16.0 ------- From c88606da1f784f7ef597ba0e0aba2167f067bdc0 Mon Sep 17 00:00:00 2001 From: Elaine Chen Date: Mon, 13 Apr 2026 10:53:27 -0400 Subject: [PATCH 5/8] Fix formatting --- mediafile/__init__.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/mediafile/__init__.py b/mediafile/__init__.py index 71b1b98..fb90e11 100644 --- a/mediafile/__init__.py +++ b/mediafile/__init__.py @@ -197,9 +197,7 @@ def __init__(self, filething, id3v23=False): } audio_fmt = getattr(self.mgfile.info, "audio_format", 0x0001) if audio_fmt in _unsupported_wav_formats: - raise FileTypeError( - self.filename, _unsupported_wav_formats[audio_fmt] - ) + raise FileTypeError(self.filename, _unsupported_wav_formats[audio_fmt]) self.type = "wav" else: raise FileTypeError(self.filename, type(self.mgfile).__name__) From 227b1b0c11f874ac54cab27aa87fcef32a5e674b Mon Sep 17 00:00:00 2001 From: Elaine Chen Date: Mon, 13 Apr 2026 18:11:47 -0400 Subject: [PATCH 6/8] Use pytest.raises and fix docs formatting --- docs/changelog.rst | 9 +++++---- test/test_mediafile_edge.py | 4 +++- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/docs/changelog.rst b/docs/changelog.rst index 1596573..2de9fb4 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -3,10 +3,11 @@ Changelog Upcoming -------- -- Raise ``FileTypeError`` for WAV files containing non-PCM audio streams - that mutagen cannot tag correctly, including ``WAVE_FORMAT_MPEGLAYER3`` - (0x0055), ``WAVE_FORMAT_ADPCM`` (0x0002), ``WAVE_FORMAT_ALAW`` (0x0006), - and ``WAVE_FORMAT_MULAW`` (0x0007). + +- Raise ``FileTypeError`` for WAV files containing non-PCM audio streams that + mutagen cannot tag correctly, including ``WAVE_FORMAT_MPEGLAYER3`` (0x0055), + ``WAVE_FORMAT_ADPCM`` (0x0002), ``WAVE_FORMAT_ALAW`` (0x0006), and + ``WAVE_FORMAT_MULAW`` (0x0007). v0.16.0 ------- diff --git a/test/test_mediafile_edge.py b/test/test_mediafile_edge.py index 570f6fe..0f4bb5b 100644 --- a/test/test_mediafile_edge.py +++ b/test/test_mediafile_edge.py @@ -19,6 +19,7 @@ import unittest import mutagen.id3 +import pytest import mediafile from test import _common @@ -177,7 +178,8 @@ def test_mpeglayer3_wav_raises_filetypeerror(self): # WAV files with WAVE_FORMAT_MPEGLAYER3 (OxOO55) contain a MP3 stream # and cannot be tagged correctly fn = os.path.join(_common.RSRC, b"mpeglayer3.wav") - self.assertRaises(mediafile.FileTypeError, mediafile.MediaFile, fn) + with pytest.raises(mediafile.FileTypeError): + mediafile.MediaFile(fn) class SideEffectsTest(unittest.TestCase): From 68243dfc42d170712d2f921aa325b07f6c86af4a Mon Sep 17 00:00:00 2001 From: Elaine Chen Date: Mon, 13 Apr 2026 19:04:31 -0400 Subject: [PATCH 7/8] Fixed dependencies --- .github/workflows/lint.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index a4169b4..015c3d9 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -106,7 +106,7 @@ jobs: cache: poetry - name: Install dependencies - run: poetry install --only=lint + run: poetry install - name: Type check code uses: liskin/gh-problem-matcher-wrap@v3 From bad50969a833f5050474f16913f11b4d5ad3f951 Mon Sep 17 00:00:00 2001 From: Elaine Chen Date: Mon, 13 Apr 2026 23:32:18 -0400 Subject: [PATCH 8/8] Fixed typo in comment --- test/test_mediafile_edge.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_mediafile_edge.py b/test/test_mediafile_edge.py index 0f4bb5b..20c6a67 100644 --- a/test/test_mediafile_edge.py +++ b/test/test_mediafile_edge.py @@ -175,7 +175,7 @@ def test_broken_symlink(self): os.unlink(fn) def test_mpeglayer3_wav_raises_filetypeerror(self): - # WAV files with WAVE_FORMAT_MPEGLAYER3 (OxOO55) contain a MP3 stream + # WAV files with WAVE_FORMAT_MPEGLAYER3 (0x0055) contain a MP3 stream # and cannot be tagged correctly fn = os.path.join(_common.RSRC, b"mpeglayer3.wav") with pytest.raises(mediafile.FileTypeError):