gh-77171: Fixes SubFormat check to compare the entire value. Add docs (GH-97509)

This commit is contained in:
Steve Dower 2022-09-23 16:08:21 +01:00 committed by GitHub
parent f1cca801f5
commit a4ac14faa5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 21 additions and 6 deletions

View file

@ -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:

View file

@ -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)

View file

@ -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 @@ def _read_fmt_chunk(self, chunk):
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')