]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Issue #19623: Fixed writing to unseekable files in the aifc module.
authorSerhiy Storchaka <storchaka@gmail.com>
Sat, 14 Dec 2013 18:35:04 +0000 (20:35 +0200)
committerSerhiy Storchaka <storchaka@gmail.com>
Sat, 14 Dec 2013 18:35:04 +0000 (20:35 +0200)
Lib/aifc.py
Lib/test/audiotests.py
Lib/test/test_aifc.py
Lib/test/test_sunau.py
Lib/test/test_wave.py
Misc/NEWS

index 86a5edc8c987ce4d9a6af68874af343d19fe3ecf..db0924a2b7f18e31dae8cce632022cc18995c536 100644 (file)
@@ -771,7 +771,10 @@ class Aifc_write:
                 self._datalength = (self._datalength + 3) // 4
                 if self._datalength & 1:
                     self._datalength = self._datalength + 1
-        self._form_length_pos = self._file.tell()
+        try:
+            self._form_length_pos = self._file.tell()
+        except (AttributeError, OSError):
+            self._form_length_pos = None
         commlength = self._write_form_length(self._datalength)
         if self._aifc:
             self._file.write(b'AIFC')
@@ -783,7 +786,8 @@ class Aifc_write:
         self._file.write(b'COMM')
         _write_ulong(self._file, commlength)
         _write_short(self._file, self._nchannels)
-        self._nframes_pos = self._file.tell()
+        if self._form_length_pos is not None:
+            self._nframes_pos = self._file.tell()
         _write_ulong(self._file, self._nframes)
         if self._comptype in (b'ULAW', b'ulaw', b'ALAW', b'alaw', b'G722'):
             _write_short(self._file, 8)
@@ -794,7 +798,8 @@ class Aifc_write:
             self._file.write(self._comptype)
             _write_string(self._file, self._compname)
         self._file.write(b'SSND')
-        self._ssnd_length_pos = self._file.tell()
+        if self._form_length_pos is not None:
+            self._ssnd_length_pos = self._file.tell()
         _write_ulong(self._file, self._datalength + 8)
         _write_ulong(self._file, 0)
         _write_ulong(self._file, 0)
index 008281f9af22695b5036cefdefadc02c5fcfcf54..6ff5bb81bbac408ce37d9e5920c6b37eaec3e8d7 100644 (file)
@@ -5,6 +5,13 @@ import io
 import pickle
 import sys
 
+class UnseekableIO(io.FileIO):
+    def tell(self):
+        raise io.UnsupportedOperation
+
+    def seek(self, *args, **kwargs):
+        raise io.UnsupportedOperation
+
 def byteswap2(data):
     a = array.array('h')
     a.frombytes(data)
@@ -129,6 +136,61 @@ class AudioWriteTests(AudioTests):
             self.assertEqual(testfile.read(13), b'ababagalamaga')
             self.check_file(testfile, self.nframes, self.frames)
 
+    def test_unseekable_read(self):
+        f = self.create_file(TESTFN)
+        f.setnframes(self.nframes)
+        f.writeframes(self.frames)
+        f.close()
+
+        with UnseekableIO(TESTFN, 'rb') as testfile:
+            self.check_file(testfile, self.nframes, self.frames)
+
+    def test_unseekable_write(self):
+        with UnseekableIO(TESTFN, 'wb') as testfile:
+            f = self.create_file(testfile)
+            f.setnframes(self.nframes)
+            f.writeframes(self.frames)
+            f.close()
+
+        self.check_file(TESTFN, self.nframes, self.frames)
+
+    def test_unseekable_incompleted_write(self):
+        with UnseekableIO(TESTFN, 'wb') as testfile:
+            testfile.write(b'ababagalamaga')
+            f = self.create_file(testfile)
+            f.setnframes(self.nframes + 1)
+            try:
+                f.writeframes(self.frames)
+            except OSError:
+                pass
+            try:
+                f.close()
+            except OSError:
+                pass
+
+        with open(TESTFN, 'rb') as testfile:
+            self.assertEqual(testfile.read(13), b'ababagalamaga')
+            self.check_file(testfile, self.nframes + 1, self.frames)
+
+    def test_unseekable_overflowed_write(self):
+        with UnseekableIO(TESTFN, 'wb') as testfile:
+            testfile.write(b'ababagalamaga')
+            f = self.create_file(testfile)
+            f.setnframes(self.nframes - 1)
+            try:
+                f.writeframes(self.frames)
+            except OSError:
+                pass
+            try:
+                f.close()
+            except OSError:
+                pass
+
+        with open(TESTFN, 'rb') as testfile:
+            self.assertEqual(testfile.read(13), b'ababagalamaga')
+            framesize = self.nchannels * self.sampwidth
+            self.check_file(testfile, self.nframes - 1, self.frames[:-framesize])
+
 
 class AudioTestsWithSourceFile(AudioTests):
 
index b77354bb0705d03d1d4c0e6a204aeaf76e760b7b..10260e3269fb700c4316abafb20b2dbabb06d8e4 100644 (file)
@@ -8,10 +8,14 @@ import struct
 import aifc
 
 
-class AifcPCM8Test(audiotests.AudioWriteTests,
-        audiotests.AudioTestsWithSourceFile,
-        unittest.TestCase):
+class AifcTest(audiotests.AudioWriteTests,
+               audiotests.AudioTestsWithSourceFile):
     module = aifc
+    close_fd = True
+    test_unseekable_read = None
+
+
+class AifcPCM8Test(AifcTest, unittest.TestCase):
     sndfilename = 'pluck-pcm8.aiff'
     sndfilenframes = 3307
     nchannels = 2
@@ -26,13 +30,9 @@ class AifcPCM8Test(audiotests.AudioWriteTests,
       11FA 3EFB BCFC 66FF CF04 4309 C10E 5112 EE17 8216 7F14 8012 \
       490E 520D EF0F CE0F E40C 630A 080A 2B0B 510E 8B11 B60E 440A \
       """)
-    close_fd = True
 
 
-class AifcPCM16Test(audiotests.AudioWriteTests,
-        audiotests.AudioTestsWithSourceFile,
-        unittest.TestCase):
-    module = aifc
+class AifcPCM16Test(AifcTest, unittest.TestCase):
     sndfilename = 'pluck-pcm16.aiff'
     sndfilenframes = 3307
     nchannels = 2
@@ -49,13 +49,9 @@ class AifcPCM16Test(audiotests.AudioWriteTests,
       EEE21753 82071665 7FFF1443 8004128F 49A20EAF 52BB0DBA EFB40F60 CE3C0FBF \
       E4B30CEC 63430A5C 08C80A20 2BBB0B08 514A0E43 8BCF1139 B6F60EEB 44120A5E \
       """)
-    close_fd = True
 
 
-class AifcPCM24Test(audiotests.AudioWriteTests,
-        audiotests.AudioTestsWithSourceFile,
-        unittest.TestCase):
-    module = aifc
+class AifcPCM24Test(AifcTest, unittest.TestCase):
     sndfilename = 'pluck-pcm24.aiff'
     sndfilenframes = 3307
     nchannels = 2
@@ -78,13 +74,9 @@ class AifcPCM24Test(audiotests.AudioWriteTests,
       E4B49C0CEA2D 6344A80A5A7C 08C8FE0A1FFE 2BB9860B0A0E \
       51486F0E44E1 8BCC64113B05 B6F4EC0EEB36 4413170A5B48 \
       """)
-    close_fd = True
 
 
-class AifcPCM32Test(audiotests.AudioWriteTests,
-        audiotests.AudioTestsWithSourceFile,
-        unittest.TestCase):
-    module = aifc
+class AifcPCM32Test(AifcTest, unittest.TestCase):
     sndfilename = 'pluck-pcm32.aiff'
     sndfilenframes = 3307
     nchannels = 2
@@ -107,13 +99,9 @@ class AifcPCM32Test(audiotests.AudioWriteTests,
       E4B49CC00CEA2D90 6344A8800A5A7CA0 08C8FE800A1FFEE0 2BB986C00B0A0E00 \
       51486F800E44E190 8BCC6480113B0580 B6F4EC000EEB3630 441317800A5B48A0 \
       """)
-    close_fd = True
 
 
-class AifcULAWTest(audiotests.AudioWriteTests,
-        audiotests.AudioTestsWithSourceFile,
-        unittest.TestCase):
-    module = aifc
+class AifcULAWTest(AifcTest, unittest.TestCase):
     sndfilename = 'pluck-ulaw.aifc'
     sndfilenframes = 3307
     nchannels = 2
@@ -132,13 +120,9 @@ class AifcULAWTest(audiotests.AudioWriteTests,
       """)
     if sys.byteorder != 'big':
         frames = audiotests.byteswap2(frames)
-    close_fd = True
 
 
-class AifcALAWTest(audiotests.AudioWriteTests,
-        audiotests.AudioTestsWithSourceFile,
-        unittest.TestCase):
-    module = aifc
+class AifcALAWTest(AifcTest, unittest.TestCase):
     sndfilename = 'pluck-alaw.aifc'
     sndfilenframes = 3307
     nchannels = 2
@@ -157,7 +141,6 @@ class AifcALAWTest(audiotests.AudioWriteTests,
       """)
     if sys.byteorder != 'big':
         frames = audiotests.byteswap2(frames)
-    close_fd = True
 
 
 class AifcMiscTest(audiotests.AudioTests, unittest.TestCase):
index 767314f5b27f113d446eecb83d96d5bf995d5389..1655317c07e37d3278a3dac06b39b76e60f694b2 100644 (file)
@@ -5,10 +5,12 @@ import sys
 import sunau
 
 
-class SunauPCM8Test(audiotests.AudioWriteTests,
-        audiotests.AudioTestsWithSourceFile,
-        unittest.TestCase):
+class SunauTest(audiotests.AudioWriteTests,
+                audiotests.AudioTestsWithSourceFile):
     module = sunau
+
+
+class SunauPCM8Test(SunauTest, unittest.TestCase):
     sndfilename = 'pluck-pcm8.au'
     sndfilenframes = 3307
     nchannels = 2
@@ -25,10 +27,7 @@ class SunauPCM8Test(audiotests.AudioWriteTests,
       """)
 
 
-class SunauPCM16Test(audiotests.AudioWriteTests,
-        audiotests.AudioTestsWithSourceFile,
-        unittest.TestCase):
-    module = sunau
+class SunauPCM16Test(SunauTest, unittest.TestCase):
     sndfilename = 'pluck-pcm16.au'
     sndfilenframes = 3307
     nchannels = 2
@@ -47,10 +46,7 @@ class SunauPCM16Test(audiotests.AudioWriteTests,
       """)
 
 
-class SunauPCM32Test(audiotests.AudioWriteTests,
-        audiotests.AudioTestsWithSourceFile,
-        unittest.TestCase):
-    module = sunau
+class SunauPCM32Test(SunauTest, unittest.TestCase):
     sndfilename = 'pluck-pcm32.au'
     sndfilenframes = 3307
     nchannels = 2
@@ -75,10 +71,7 @@ class SunauPCM32Test(audiotests.AudioWriteTests,
       """)
 
 
-class SunauULAWTest(audiotests.AudioWriteTests,
-        audiotests.AudioTestsWithSourceFile,
-        unittest.TestCase):
-    module = sunau
+class SunauULAWTest(SunauTest, unittest.TestCase):
     sndfilename = 'pluck-ulaw.au'
     sndfilenframes = 3307
     nchannels = 2
index 5be12519d9e4bb5d9895e4ee28565cb719d5f509..f64201f9fc648377fe928291223bb05d5899b630 100644 (file)
@@ -5,10 +5,15 @@ import sys
 import wave
 
 
-class WavePCM8Test(audiotests.AudioWriteTests,
-        audiotests.AudioTestsWithSourceFile,
-        unittest.TestCase):
+class WaveTest(audiotests.AudioWriteTests,
+               audiotests.AudioTestsWithSourceFile):
     module = wave
+    test_unseekable_write = None
+    test_unseekable_overflowed_write = None
+    test_unseekable_incompleted_write = None
+
+
+class WavePCM8Test(WaveTest, unittest.TestCase):
     sndfilename = 'pluck-pcm8.wav'
     sndfilenframes = 3307
     nchannels = 2
@@ -25,10 +30,7 @@ class WavePCM8Test(audiotests.AudioWriteTests,
       """)
 
 
-class WavePCM16Test(audiotests.AudioWriteTests,
-        audiotests.AudioTestsWithSourceFile,
-        unittest.TestCase):
-    module = wave
+class WavePCM16Test(WaveTest, unittest.TestCase):
     sndfilename = 'pluck-pcm16.wav'
     sndfilenframes = 3307
     nchannels = 2
@@ -55,10 +57,7 @@ class WavePCM16Test(audiotests.AudioWriteTests,
 
 
 
-class WavePCM24Test(audiotests.AudioWriteTests,
-        audiotests.AudioTestsWithSourceFile,
-        unittest.TestCase):
-    module = wave
+class WavePCM24Test(WaveTest, unittest.TestCase):
     sndfilename = 'pluck-pcm24.wav'
     sndfilenframes = 3307
     nchannels = 2
@@ -85,10 +84,7 @@ class WavePCM24Test(audiotests.AudioWriteTests,
         frames = audiotests.byteswap3(frames)
 
 
-class WavePCM32Test(audiotests.AudioWriteTests,
-        audiotests.AudioTestsWithSourceFile,
-        unittest.TestCase):
-    module = wave
+class WavePCM32Test(WaveTest, unittest.TestCase):
     sndfilename = 'pluck-pcm32.wav'
     sndfilenframes = 3307
     nchannels = 2
index b5f1ece6a68c61a061925c97386b7df619d6048a..462d649d74498f09a9abf98909c6e293628290c9 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -32,6 +32,8 @@ Core and Builtins
 Library
 -------
 
+- Issue #19623: Fixed writing to unseekable files in the aifc module.
+
 - Issue #17919: select.poll.register() again works with poll.POLLNVAL on AIX.
   Fixed integer overflow in the eventmask parameter.