当前仓库属于关闭状态,部分功能使用受限,详情请查阅 仓库状态说明
25 Star 1 Fork 13

src-openEuler / python2
关闭

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
CVE-2017-18207.patch 12.37 KB
一键复制 编辑 原始数据 按行查看 历史
From 3c0a5a7c7ba8fbbc95dd1fe76cd7a1c0ce167371 Mon Sep 17 00:00:00 2001
From: "Miss Islington (bot)"
<31488909+miss-islington@users.noreply.github.com>
Date: Sun, 18 Mar 2018 13:50:41 -0700
Subject: [PATCH] bpo-32056: Improve exceptions in aifc, wave and sunau.
(GH-5951)
(cherry picked from commit 134cb01cda50f02725575808130b05d2d776693f)
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
---
Lib/aifc.py | 4 ++
Lib/sunau.py | 2 +
Lib/test/test_aifc.py | 35 +++++++++--
Lib/test/test_sunau.py | 36 +++++++++++
Lib/test/test_wave.py | 61 +++++++++++++++++++
Lib/wave.py | 14 ++++-
.../2018-03-01-17-49-56.bpo-32056.IlpfgE.rst | 3 +
7 files changed, 148 insertions(+), 7 deletions(-)
create mode 100644 Misc/NEWS.d/next/Library/2018-03-01-17-49-56.bpo-32056.IlpfgE.rst
diff --git a/Lib/aifc.py b/Lib/aifc.py
index 981f801..d0e5e02 100644
--- a/Lib/aifc.py
+++ b/Lib/aifc.py
@@ -465,6 +465,10 @@ class Aifc_read:
self._nframes = _read_long(chunk)
self._sampwidth = (_read_short(chunk) + 7) // 8
self._framerate = int(_read_float(chunk))
+ if self._sampwidth <= 0:
+ raise Error('bad sample width')
+ if self._nchannels <= 0:
+ raise Error('bad # of channels')
self._framesize = self._nchannels * self._sampwidth
if self._aifc:
#DEBUG: SGI's soundeditor produces a bad size :-(
diff --git a/Lib/sunau.py b/Lib/sunau.py
index b53044d..b5d83ea 100644
--- a/Lib/sunau.py
+++ b/Lib/sunau.py
@@ -194,6 +194,8 @@ class Au_read:
raise Error, 'unknown encoding'
self._framerate = int(_read_u32(file))
self._nchannels = int(_read_u32(file))
+ if not self._nchannels:
+ raise Error('bad # of channels')
self._framesize = self._framesize * self._nchannels
if self._hdr_size > 24:
self._info = file.read(self._hdr_size - 24)
diff --git a/Lib/test/test_aifc.py b/Lib/test/test_aifc.py
index 92bbe7b..6517c9f 100644
--- a/Lib/test/test_aifc.py
+++ b/Lib/test/test_aifc.py
@@ -216,7 +216,8 @@ class AIFCLowLevelTest(unittest.TestCase):
def test_read_no_ssnd_chunk(self):
b = b'FORM' + struct.pack('>L', 4) + b'AIFC'
- b += b'COMM' + struct.pack('>LhlhhLL', 38, 0, 0, 0, 0, 0, 0)
+ b += b'COMM' + struct.pack('>LhlhhLL', 38, 1, 0, 8,
+ 0x4000 | 12, 11025<<18, 0)
b += b'NONE' + struct.pack('B', 14) + b'not compressed' + b'\x00'
with self.assertRaisesRegexp(aifc.Error, 'COMM chunk and/or SSND chunk'
' missing'):
@@ -224,13 +225,35 @@ class AIFCLowLevelTest(unittest.TestCase):
def test_read_wrong_compression_type(self):
b = 'FORM' + struct.pack('>L', 4) + 'AIFC'
- b += 'COMM' + struct.pack('>LhlhhLL', 23, 0, 0, 0, 0, 0, 0)
+ b += b'COMM' + struct.pack('>LhlhhLL', 23, 1, 0, 8,
+ 0x4000 | 12, 11025<<18, 0)
b += 'WRNG' + struct.pack('B', 0)
self.assertRaises(aifc.Error, aifc.open, io.BytesIO(b))
+ def test_read_wrong_number_of_channels(self):
+ for nchannels in 0, -1:
+ b = b'FORM' + struct.pack('>L', 4) + b'AIFC'
+ b += b'COMM' + struct.pack('>LhlhhLL', 38, nchannels, 0, 8,
+ 0x4000 | 12, 11025<<18, 0)
+ b += b'NONE' + struct.pack('B', 14) + b'not compressed' + b'\x00'
+ b += b'SSND' + struct.pack('>L', 8) + b'\x00' * 8
+ with self.assertRaisesRegex(aifc.Error, 'bad # of channels'):
+ aifc.open(io.BytesIO(b))
+
+ def test_read_wrong_sample_width(self):
+ for sampwidth in 0, -1:
+ b = b'FORM' + struct.pack('>L', 4) + b'AIFC'
+ b += b'COMM' + struct.pack('>LhlhhLL', 38, 1, 0, sampwidth,
+ 0x4000 | 12, 11025<<18, 0)
+ b += b'NONE' + struct.pack('B', 14) + b'not compressed' + b'\x00'
+ b += b'SSND' + struct.pack('>L', 8) + b'\x00' * 8
+ with self.assertRaisesRegex(aifc.Error, 'bad sample width'):
+ aifc.open(io.BytesIO(b))
+
def test_read_wrong_marks(self):
b = 'FORM' + struct.pack('>L', 4) + 'AIFF'
- b += 'COMM' + struct.pack('>LhlhhLL', 18, 0, 0, 0, 0, 0, 0)
+ b += b'COMM' + struct.pack('>LhlhhLL', 18, 1, 0, 8,
+ 0x4000 | 12, 11025<<18, 0)
b += 'SSND' + struct.pack('>L', 8) + '\x00' * 8
b += 'MARK' + struct.pack('>LhB', 3, 1, 1)
with captured_stdout() as s:
@@ -241,7 +264,8 @@ class AIFCLowLevelTest(unittest.TestCase):
def test_read_comm_kludge_compname_even(self):
b = 'FORM' + struct.pack('>L', 4) + 'AIFC'
- b += 'COMM' + struct.pack('>LhlhhLL', 18, 0, 0, 0, 0, 0, 0)
+ b += b'COMM' + struct.pack('>LhlhhLL', 18, 1, 0, 8,
+ 0x4000 | 12, 11025<<18, 0)
b += 'NONE' + struct.pack('B', 4) + 'even' + '\x00'
b += 'SSND' + struct.pack('>L', 8) + '\x00' * 8
with captured_stdout() as s:
@@ -251,7 +275,8 @@ class AIFCLowLevelTest(unittest.TestCase):
def test_read_comm_kludge_compname_odd(self):
b = 'FORM' + struct.pack('>L', 4) + 'AIFC'
- b += 'COMM' + struct.pack('>LhlhhLL', 18, 0, 0, 0, 0, 0, 0)
+ b += b'COMM' + struct.pack('>LhlhhLL', 18, 1, 0, 8,
+ 0x4000 | 12, 11025<<18, 0)
b += 'NONE' + struct.pack('B', 3) + 'odd'
b += 'SSND' + struct.pack('>L', 8) + '\x00' * 8
with captured_stdout() as s:
diff --git a/Lib/test/test_sunau.py b/Lib/test/test_sunau.py
index f682868..824bd91 100644
--- a/Lib/test/test_sunau.py
+++ b/Lib/test/test_sunau.py
@@ -1,6 +1,8 @@
from test.test_support import TESTFN, run_unittest
import unittest
from test import audiotests
+import io
+import struct
import sys
import sunau
@@ -91,6 +93,40 @@ class SunauULAWTest(SunauTest, unittest.TestCase):
if sys.byteorder != 'big':
frames = audiotests.byteswap2(frames)
+class SunauLowLevelTest(unittest.TestCase):
+
+ def test_read_bad_magic_number(self):
+ b = b'SPA'
+ with self.assertRaises(EOFError):
+ sunau.open(io.BytesIO(b))
+ b = b'SPAM'
+ with self.assertRaisesRegex(sunau.Error, 'bad magic number'):
+ sunau.open(io.BytesIO(b))
+
+ def test_read_too_small_header(self):
+ b = struct.pack('>LLLLL', sunau.AUDIO_FILE_MAGIC, 20, 0,
+ sunau.AUDIO_FILE_ENCODING_LINEAR_8, 11025)
+ with self.assertRaisesRegex(sunau.Error, 'header size too small'):
+ sunau.open(io.BytesIO(b))
+
+ def test_read_too_large_header(self):
+ b = struct.pack('>LLLLLL', sunau.AUDIO_FILE_MAGIC, 124, 0,
+ sunau.AUDIO_FILE_ENCODING_LINEAR_8, 11025, 1)
+ b += b'\0' * 100
+ with self.assertRaisesRegex(sunau.Error, 'header size ridiculously large'):
+ sunau.open(io.BytesIO(b))
+
+ def test_read_wrong_encoding(self):
+ b = struct.pack('>LLLLLL', sunau.AUDIO_FILE_MAGIC, 24, 0, 0, 11025, 1)
+ with self.assertRaisesRegex(sunau.Error, r'encoding not \(yet\) supported'):
+ sunau.open(io.BytesIO(b))
+
+ def test_read_wrong_number_of_channels(self):
+ b = struct.pack('>LLLLLL', sunau.AUDIO_FILE_MAGIC, 24, 0,
+ sunau.AUDIO_FILE_ENCODING_LINEAR_8, 11025, 0)
+ with self.assertRaisesRegex(sunau.Error, 'bad # of channels'):
+ sunau.open(io.BytesIO(b))
+
def test_main():
run_unittest(SunauPCM8Test, SunauPCM16Test, SunauPCM16Test,
diff --git a/Lib/test/test_wave.py b/Lib/test/test_wave.py
index 9513df4..b835746 100644
--- a/Lib/test/test_wave.py
+++ b/Lib/test/test_wave.py
@@ -1,6 +1,8 @@
from test.test_support import TESTFN, run_unittest
import unittest
from test import audiotests
+import io
+import struct
import sys
import wave
@@ -115,6 +117,65 @@ class WavePCM32Test(WaveTest, unittest.TestCase):
def test_unseekable_incompleted_write(self):
super().test_unseekable_incompleted_write()
+class WaveLowLevelTest(unittest.TestCase):
+
+ def test_read_no_chunks(self):
+ b = b'SPAM'
+ with self.assertRaises(EOFError):
+ wave.open(io.BytesIO(b))
+
+ def test_read_no_riff_chunk(self):
+ b = b'SPAM' + struct.pack('<L', 0)
+ with self.assertRaisesRegex(wave.Error,
+ 'file does not start with RIFF id'):
+ wave.open(io.BytesIO(b))
+
+ def test_read_not_wave(self):
+ b = b'RIFF' + struct.pack('<L', 4) + b'SPAM'
+ with self.assertRaisesRegex(wave.Error,
+ 'not a WAVE file'):
+ wave.open(io.BytesIO(b))
+
+ def test_read_no_fmt_no_data_chunk(self):
+ b = b'RIFF' + struct.pack('<L', 4) + b'WAVE'
+ with self.assertRaisesRegex(wave.Error,
+ 'fmt chunk and/or data chunk missing'):
+ wave.open(io.BytesIO(b))
+
+ def test_read_no_data_chunk(self):
+ b = b'RIFF' + struct.pack('<L', 28) + b'WAVE'
+ b += b'fmt ' + struct.pack('<LHHLLHH', 16, 1, 1, 11025, 11025, 1, 8)
+ with self.assertRaisesRegex(wave.Error,
+ 'fmt chunk and/or data chunk missing'):
+ wave.open(io.BytesIO(b))
+
+ def test_read_no_fmt_chunk(self):
+ b = b'RIFF' + struct.pack('<L', 12) + b'WAVE'
+ b += b'data' + struct.pack('<L', 0)
+ with self.assertRaisesRegex(wave.Error, 'data chunk before fmt chunk'):
+ wave.open(io.BytesIO(b))
+
+ def test_read_wrong_form(self):
+ b = b'RIFF' + struct.pack('<L', 36) + b'WAVE'
+ b += b'fmt ' + struct.pack('<LHHLLHH', 16, 2, 1, 11025, 11025, 1, 1)
+ b += b'data' + struct.pack('<L', 0)
+ with self.assertRaisesRegex(wave.Error, 'unknown format: 2'):
+ wave.open(io.BytesIO(b))
+
+ def test_read_wrong_number_of_channels(self):
+ b = b'RIFF' + struct.pack('<L', 36) + b'WAVE'
+ b += b'fmt ' + struct.pack('<LHHLLHH', 16, 1, 0, 11025, 11025, 1, 8)
+ b += b'data' + struct.pack('<L', 0)
+ with self.assertRaisesRegex(wave.Error, 'bad # of channels'):
+ wave.open(io.BytesIO(b))
+
+ def test_read_wrong_sample_width(self):
+ b = b'RIFF' + struct.pack('<L', 36) + b'WAVE'
+ b += b'fmt ' + struct.pack('<LHHLLHH', 16, 1, 1, 11025, 11025, 1, 0)
+ b += b'data' + struct.pack('<L', 0)
+ with self.assertRaisesRegex(wave.Error, 'bad sample width'):
+ wave.open(io.BytesIO(b))
+
def test_main():
run_unittest(WavePCM8Test, WavePCM16Test, WavePCM24Test, WavePCM32Test)
diff --git a/Lib/wave.py b/Lib/wave.py
index 28acaa6..63c196f 100644
--- a/Lib/wave.py
+++ b/Lib/wave.py
@@ -266,12 +266,22 @@ class Wave_read:
#
def _read_fmt_chunk(self, chunk):
- wFormatTag, self._nchannels, self._framerate, dwAvgBytesPerSec, wBlockAlign = struct.unpack('<HHLLH', chunk.read(14))
+ try:
+ wFormatTag, self._nchannels, self._framerate, dwAvgBytesPerSec, wBlockAlign = struct.unpack_from('<HHLLH', chunk.read(14))
+ except struct.error:
+ raise EOFError
if wFormatTag == WAVE_FORMAT_PCM:
- sampwidth = struct.unpack('<H', chunk.read(2))[0]
+ try:
+ sampwidth = struct.unpack_from('<H', chunk.read(2))[0]
+ except struct.error:
+ raise EOFError
self._sampwidth = (sampwidth + 7) // 8
+ if not self._sampwidth:
+ raise Error('bad sample width')
else:
raise Error, 'unknown format: %r' % (wFormatTag,)
+ if not self._nchannels:
+ raise Error('bad # of channels')
self._framesize = self._nchannels * self._sampwidth
self._comptype = 'NONE'
self._compname = 'not compressed'
diff --git a/Misc/NEWS.d/next/Library/2018-03-01-17-49-56.bpo-32056.IlpfgE.rst b/Misc/NEWS.d/next/Library/2018-03-01-17-49-56.bpo-32056.IlpfgE.rst
new file mode 100644
index 0000000..421aa37
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2018-03-01-17-49-56.bpo-32056.IlpfgE.rst
@@ -0,0 +1,3 @@
+Improved exceptions raised for invalid number of channels and sample width
+when read an audio file in modules :mod:`aifc`, :mod:`wave` and
+:mod:`sunau`.
--
2.23.0
1
https://gitee.com/src-openeuler/python2.git
git@gitee.com:src-openeuler/python2.git
src-openeuler
python2
python2
master

搜索帮助