diff --git a/Lib/test/test_wave.py b/Lib/test/test_wave.py index 4c21f16553775c..e77f026d1df916 100644 --- a/Lib/test/test_wave.py +++ b/Lib/test/test_wave.py @@ -207,6 +207,30 @@ def test_open_in_write_raises(self): support.gc_collect() self.assertIsNone(cm.unraisable) + def test_write_odd_data_chunk_pads_and_updates_riff_size(self): + # gh-117716: odd-sized data chunks must be padded with one zero byte. + with io.BytesIO() as output: + with wave.open(output, mode='wb') as w: + w.setnchannels(1) + w.setsampwidth(1) + w.setframerate(48000) + w.writeframes(b'\x80') + + value = output.getvalue() + + self.assertEqual(value[-1], 0) + self.assertEqual( + int.from_bytes(value[4:8], byteorder='little'), + 38, + ) + + with wave.open(io.BytesIO(value), mode='rb') as r: + self.assertEqual(r.getnchannels(), 1) + self.assertEqual(r.getsampwidth(), 1) + self.assertEqual(r.getframerate(), 48000) + self.assertEqual(r.getnframes(), 1) + self.assertEqual(r.readframes(-1), b'\x80') + class WaveOpen(unittest.TestCase): def test_open_pathlike(self): diff --git a/Lib/wave.py b/Lib/wave.py index 25ca9ef168e8a5..2a26f8d3b3663a 100644 --- a/Lib/wave.py +++ b/Lib/wave.py @@ -565,6 +565,8 @@ def close(self): try: if self._file: self._ensure_header_written(0) + if self._datawritten & 1: + self._file.write(b'\x00') if self._datalength != self._datawritten: self._patchheader() self._file.flush() @@ -600,7 +602,7 @@ def _write_header(self, initlength): except (AttributeError, OSError): self._form_length_pos = None self._file.write(struct.pack('