Skip to content

Commit a4ac14f

Browse files
authored
gh-77171: Fixes SubFormat check to compare the entire value. Add docs (GH-97509)
1 parent f1cca80 commit a4ac14f

File tree

3 files changed

+21
-6
lines changed

3 files changed

+21
-6
lines changed

Doc/library/wave.rst

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,12 @@
1212
--------------
1313

1414
The :mod:`wave` module provides a convenient interface to the WAV sound format.
15-
It does not support compression/decompression, but it does support mono/stereo.
15+
Only PCM encoded wave files are supported.
16+
17+
.. versionchanged:: 3.12
18+
19+
Support for ``WAVE_FORMAT_EXTENSIBLE`` headers was added, provided that the
20+
extended format is ``KSDATAFORMAT_SUBTYPE_PCM``.
1621

1722
The :mod:`wave` module defines the following function and exception:
1823

Lib/test/test_wave.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ class WavePCM32Test(WaveTest, unittest.TestCase):
133133

134134
class MiscTestCase(unittest.TestCase):
135135
def test__all__(self):
136-
not_exported = {'WAVE_FORMAT_PCM', 'WAVE_FORMAT_EXTENSIBLE'}
136+
not_exported = {'WAVE_FORMAT_PCM', 'WAVE_FORMAT_EXTENSIBLE', 'KSDATAFORMAT_SUBTYPE_PCM'}
137137
support.check__all__(self, wave, not_exported=not_exported)
138138

139139

Lib/wave.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ class Error(Exception):
8484

8585
WAVE_FORMAT_PCM = 0x0001
8686
WAVE_FORMAT_EXTENSIBLE = 0xFFFE
87+
# Derived from uuid.UUID("00000001-0000-0010-8000-00aa00389b71").bytes_le
88+
KSDATAFORMAT_SUBTYPE_PCM = b'\x01\x00\x00\x00\x00\x00\x10\x00\x80\x00\x00\xaa\x008\x9bq'
8789

8890
_array_fmts = None, 'b', 'h', None, 'i'
8991

@@ -386,12 +388,20 @@ def _read_fmt_chunk(self, chunk):
386388
raise EOFError from None
387389
if wFormatTag == WAVE_FORMAT_EXTENSIBLE:
388390
try:
389-
# Only the first 2 bytes (of 16) of SubFormat are needed.
390-
cbSize, wValidBitsPerSample, dwChannelMask, SubFormatFmt = struct.unpack_from('<HHLH', chunk.read(10))
391+
cbSize, wValidBitsPerSample, dwChannelMask = struct.unpack_from('<HHL', chunk.read(8))
392+
# Read the entire UUID from the chunk
393+
SubFormat = chunk.read(16)
394+
if len(SubFormat) < 16:
395+
raise EOFError
391396
except struct.error:
392397
raise EOFError from None
393-
if SubFormatFmt != WAVE_FORMAT_PCM:
394-
raise Error(f'unknown format: {SubFormatFmt}')
398+
if SubFormat != KSDATAFORMAT_SUBTYPE_PCM:
399+
try:
400+
import uuid
401+
subformat_msg = f'unknown extended format: {uuid.UUID(bytes_le=SubFormat)}'
402+
except Exception:
403+
subformat_msg = 'unknown extended format'
404+
raise Error(subformat_msg)
395405
self._sampwidth = (sampwidth + 7) // 8
396406
if not self._sampwidth:
397407
raise Error('bad sample width')

0 commit comments

Comments
 (0)