diff -r 454b97887c5a Lib/aifc.py --- a/Lib/aifc.py Fri Dec 02 19:49:02 2011 +0200 +++ b/Lib/aifc.py Fri Dec 30 14:29:36 2011 +0400 @@ -274,7 +274,8 @@ # _ssnd_seek_needed -- 1 iff positioned correctly in audio # file for readframes() # _ssnd_chunk -- instantiation of a chunk class for the SSND chunk - # _framesize -- size of one frame in the file + # _framesize -- size in bits of one frame in the file: G722 uses + # 4 bits per sample, which can result in single frame size < 1 byte def initfp(self, file): self._version = 0 @@ -384,13 +385,13 @@ if self._ssnd_seek_needed: self._ssnd_chunk.seek(0) dummy = self._ssnd_chunk.read(8) - pos = self._soundpos * self._framesize + pos = (self._soundpos * self._framesize) // 8 if pos: self._ssnd_chunk.seek(pos + 8) self._ssnd_seek_needed = 0 if nframes == 0: return b'' - data = self._ssnd_chunk.read(nframes * self._framesize) + data = self._ssnd_chunk.read((nframes * self._framesize) // 8) if self._convert and data: data = self._convert(data) self._soundpos = self._soundpos + len(data) // (self._nchannels @@ -422,7 +423,7 @@ self._nframes = _read_long(chunk) self._sampwidth = (_read_short(chunk) + 7) // 8 self._framerate = int(_read_float(chunk)) - self._framesize = self._nchannels * self._sampwidth + self._framesize = self._nchannels * self._sampwidth * 8 if self._aifc: #DEBUG: SGI's soundeditor produces a bad size :-( kludge = 0 diff -r 454b97887c5a Lib/test/test_aifc.py --- a/Lib/test/test_aifc.py Fri Dec 02 19:49:02 2011 +0200 +++ b/Lib/test/test_aifc.py Fri Dec 30 14:29:36 2011 +0400 @@ -109,6 +109,23 @@ f.close() self.assertEqual(testfile.closed, True) + def test_read_compressed_frames(self): + def check_frames(comptype, nframes, sampwidth): + fout = self.fout = aifc.open(TESTFN, 'wb') + fout.aifc() + fout.setparams((1, sampwidth, 1, nframes, comptype, b'')) + frames = b'\x00' * nframes * fout.getnchannels() * sampwidth + fout.writeframes(frames) + fout.close() + f = self.f = aifc.open(TESTFN, 'rb') + self.assertEqual(len(f.readframes(nframes)), len(frames)) + f.close() + for comptype in (b'ULAW', b'ulaw', b'ALAW', b'alaw'): + for nframes in (1, 2): + check_frames(comptype, nframes, 2) + for nframes in (2, 4): + check_frames(b'G722', nframes, 2) + def test_main(): run_unittest(AIFCTest) diff -r 454b97887c5a Lib/test/test_audioop.py --- a/Lib/test/test_audioop.py Fri Dec 02 19:49:02 2011 +0200 +++ b/Lib/test/test_audioop.py Fri Dec 30 14:29:36 2011 +0400 @@ -195,10 +195,15 @@ self.assertRaises(audioop.error, audioop.lin2lin, data, size, size2) self.assertRaises(audioop.error, audioop.ratecv, data, size, 1, 1, 1, state) self.assertRaises(audioop.error, audioop.lin2ulaw, data, size) + self.assertRaises(audioop.error, audioop.lin2alaw, data, size) + self.assertRaises(audioop.error, audioop.lin2adpcm, data, size, state) + + def test_wrongsize(self): + data = 'abc' + state = None + for size in (-1, 3, 5): self.assertRaises(audioop.error, audioop.ulaw2lin, data, size) - self.assertRaises(audioop.error, audioop.lin2alaw, data, size) self.assertRaises(audioop.error, audioop.alaw2lin, data, size) - self.assertRaises(audioop.error, audioop.lin2adpcm, data, size, state) self.assertRaises(audioop.error, audioop.adpcm2lin, data, size, state) def test_main(): diff -r 454b97887c5a Modules/audioop.c --- a/Modules/audioop.c Fri Dec 02 19:49:02 2011 +0200 +++ b/Modules/audioop.c Fri Dec 30 14:29:36 2011 +0400 @@ -1311,7 +1311,7 @@ &cp, &len, &size) ) return 0; - if (!audioop_check_parameters(len, size)) + if (!audioop_check_parameters(len*size, size)) return NULL; if (len > PY_SSIZE_T_MAX/size) { @@ -1380,7 +1380,7 @@ &cp, &len, &size) ) return 0; - if (!audioop_check_parameters(len, size)) + if (!audioop_check_parameters(len*size, size)) return NULL; if (len > PY_SSIZE_T_MAX/size) { @@ -1524,7 +1524,7 @@ &cp, &len, &size, &state) ) return 0; - if (!audioop_check_parameters(len, size)) + if (!audioop_check_parameters(len*size, size)) return NULL; /* Decode state, should have (value, step) */