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 diff --git a/docs/changelog.rst b/docs/changelog.rst index 14ddee0..2de9fb4 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -4,6 +4,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). + v0.16.0 ------- diff --git a/mediafile/__init__.py b/mediafile/__init__.py index 7b2cb8a..fb90e11 100644 --- a/mediafile/__init__.py +++ b/mediafile/__init__.py @@ -187,6 +187,17 @@ def __init__(self, filething, id3v23=False): elif type(self.mgfile).__name__ == "DSF": self.type = "dsf" elif type(self.mgfile).__name__ == "WAVE": + # 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__) diff --git a/test/rsrc/mpeglayer3.wav b/test/rsrc/mpeglayer3.wav new file mode 100644 index 0000000..89f933f Binary files /dev/null and b/test/rsrc/mpeglayer3.wav differ diff --git a/test/test_mediafile_edge.py b/test/test_mediafile_edge.py index bf93bc7..20c6a67 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 @@ -173,6 +174,13 @@ def test_broken_symlink(self): finally: os.unlink(fn) + def test_mpeglayer3_wav_raises_filetypeerror(self): + # 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): + mediafile.MediaFile(fn) + class SideEffectsTest(unittest.TestCase): def setUp(self):