diff options
author | Steve Dower <steve.dower@python.org> | 2022-09-23 15:08:21 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-09-23 15:08:21 (GMT) |
commit | a4ac14faa5c2be433738dfbbed14b0eaa1a2399e (patch) | |
tree | 15ec10f6bde2352ebf524e97ef8df7b528dcdc9f | |
parent | f1cca801f50a92c0affede6bc22c3c1ec211358d (diff) | |
download | cpython-a4ac14faa5c2be433738dfbbed14b0eaa1a2399e.zip cpython-a4ac14faa5c2be433738dfbbed14b0eaa1a2399e.tar.gz cpython-a4ac14faa5c2be433738dfbbed14b0eaa1a2399e.tar.bz2 |
gh-77171: Fixes SubFormat check to compare the entire value. Add docs (GH-97509)
-rw-r--r-- | Doc/library/wave.rst | 7 | ||||
-rw-r--r-- | Lib/test/test_wave.py | 2 | ||||
-rw-r--r-- | Lib/wave.py | 18 |
3 files changed, 21 insertions, 6 deletions
diff --git a/Doc/library/wave.rst b/Doc/library/wave.rst index f63e0d3..04a28d9 100644 --- a/Doc/library/wave.rst +++ b/Doc/library/wave.rst @@ -12,7 +12,12 @@ -------------- The :mod:`wave` module provides a convenient interface to the WAV sound format. -It does not support compression/decompression, but it does support mono/stereo. +Only PCM encoded wave files are supported. + +.. versionchanged:: 3.12 + + Support for ``WAVE_FORMAT_EXTENSIBLE`` headers was added, provided that the + extended format is ``KSDATAFORMAT_SUBTYPE_PCM``. The :mod:`wave` module defines the following function and exception: diff --git a/Lib/test/test_wave.py b/Lib/test/test_wave.py index 35660fd..6c33628 100644 --- a/Lib/test/test_wave.py +++ b/Lib/test/test_wave.py @@ -133,7 +133,7 @@ class WavePCM32Test(WaveTest, unittest.TestCase): class MiscTestCase(unittest.TestCase): def test__all__(self): - not_exported = {'WAVE_FORMAT_PCM', 'WAVE_FORMAT_EXTENSIBLE'} + not_exported = {'WAVE_FORMAT_PCM', 'WAVE_FORMAT_EXTENSIBLE', 'KSDATAFORMAT_SUBTYPE_PCM'} support.check__all__(self, wave, not_exported=not_exported) diff --git a/Lib/wave.py b/Lib/wave.py index e446174..d5858e5 100644 --- a/Lib/wave.py +++ b/Lib/wave.py @@ -84,6 +84,8 @@ class Error(Exception): WAVE_FORMAT_PCM = 0x0001 WAVE_FORMAT_EXTENSIBLE = 0xFFFE +# Derived from uuid.UUID("00000001-0000-0010-8000-00aa00389b71").bytes_le +KSDATAFORMAT_SUBTYPE_PCM = b'\x01\x00\x00\x00\x00\x00\x10\x00\x80\x00\x00\xaa\x008\x9bq' _array_fmts = None, 'b', 'h', None, 'i' @@ -386,12 +388,20 @@ class Wave_read: raise EOFError from None if wFormatTag == WAVE_FORMAT_EXTENSIBLE: try: - # Only the first 2 bytes (of 16) of SubFormat are needed. - cbSize, wValidBitsPerSample, dwChannelMask, SubFormatFmt = struct.unpack_from('<HHLH', chunk.read(10)) + cbSize, wValidBitsPerSample, dwChannelMask = struct.unpack_from('<HHL', chunk.read(8)) + # Read the entire UUID from the chunk + SubFormat = chunk.read(16) + if len(SubFormat) < 16: + raise EOFError except struct.error: raise EOFError from None - if SubFormatFmt != WAVE_FORMAT_PCM: - raise Error(f'unknown format: {SubFormatFmt}') + if SubFormat != KSDATAFORMAT_SUBTYPE_PCM: + try: + import uuid + subformat_msg = f'unknown extended format: {uuid.UUID(bytes_le=SubFormat)}' + except Exception: + subformat_msg = 'unknown extended format' + raise Error(subformat_msg) self._sampwidth = (sampwidth + 7) // 8 if not self._sampwidth: raise Error('bad sample width') |