]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-77171: Fixes SubFormat check to compare the entire value. Add docs (GH-97509)
authorSteve Dower <steve.dower@python.org>
Fri, 23 Sep 2022 15:08:21 +0000 (16:08 +0100)
committerGitHub <noreply@github.com>
Fri, 23 Sep 2022 15:08:21 +0000 (16:08 +0100)
Doc/library/wave.rst
Lib/test/test_wave.py
Lib/wave.py

index f63e0d3dce19c6383828cf2bedbc587f88f2888b..04a28d97d619eb94eb183da5306aa6f54ac38b59 100644 (file)
 --------------
 
 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:
 
index 35660fd4d34e183a3b5c8318d83d414a98673344..6c3362857fc2ba2fec994251d6c712dca9ccc890 100644 (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)
 
 
index e446174b4b22b9ff1c0272df33c26bf3be82b076..d5858e5d4b80da1dab88973660180b9e55b83692 100644 (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 @@ 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')