]> granicus.if.org Git - python/commitdiff
bpo-29110: Fix file object leak in aifc.open (GH-356)
authorINADA Naoki <methane@users.noreply.github.com>
Tue, 28 Feb 2017 11:39:30 +0000 (20:39 +0900)
committerGitHub <noreply@github.com>
Tue, 28 Feb 2017 11:39:30 +0000 (20:39 +0900)
Lib/aifc.py
Lib/test/test_aifc.py
Misc/NEWS

index c9a021ee9d0309c3680794fc00d6781028151b7f..e6783277a471c1adcb50a3c5515743076c7fc842 100644 (file)
@@ -288,6 +288,8 @@ class Aifc_read:
     # _ssnd_chunk -- instantiation of a chunk class for the SSND chunk
     # _framesize -- size of one frame in the file
 
+    _file = None  # Set here since __del__ checks it
+
     def initfp(self, file):
         self._version = 0
         self._decomp = None
@@ -341,10 +343,16 @@ class Aifc_read:
             self._decomp.SetParams(params)
 
     def __init__(self, f):
-        if type(f) == type(''):
+        if isinstance(f, basestring):
             f = __builtin__.open(f, 'rb')
-        # else, assume it is an open file object already
-        self.initfp(f)
+            try:
+                self.initfp(f)
+            except:
+                f.close()
+                raise
+        else:
+            # assume it is an open file object already
+            self.initfp(f)
 
     #
     # User visible methods.
@@ -562,8 +570,10 @@ class Aifc_write:
     # _datalength -- the size of the audio samples written to the header
     # _datawritten -- the size of the audio samples actually written
 
+    _file = None  # Set here since __del__ checks it
+
     def __init__(self, f):
-        if type(f) == type(''):
+        if isinstance(f, basestring):
             filename = f
             f = __builtin__.open(f, 'wb')
         else:
index d4e9de595a4c7644a1ea45fc15b6bf39e4995b40..d1b7dd0432579cf84039fb08e68580cb2a0eddc3 100644 (file)
@@ -129,6 +129,18 @@ class AifcMiscTest(audiotests.AudioTests, unittest.TestCase):
         #This file contains chunk types aifc doesn't recognize.
         self.f = aifc.open(findfile('Sine-1000Hz-300ms.aif'))
 
+    def test_close_opened_files_on_error(self):
+        non_aifc_file = findfile('pluck-pcm8.wav', subdir='audiodata')
+
+        class Aifc(aifc.Aifc_read):
+            def __init__(self):
+                pass
+
+        a = Aifc()
+        with self.assertRaises(aifc.Error):
+            aifc.Aifc_read.__init__(a, non_aifc_file)
+        self.assertTrue(a._file.closed)
+
     def test_write_markers_values(self):
         fout = aifc.open(io.BytesIO(), 'wb')
         self.assertEqual(fout.getmarkers(), None)
index 5e4a3daeca263c90adac07662c7702e1b5492521..4523df5a93615555db0f07116a096d35c9693763 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -36,6 +36,10 @@ Extension Modules
 Library
 -------
 
+- bpo-29110: Fix file object leak in aifc.open() when file is given as a
+  filesystem path and is not in valid AIFF format.
+  Original patch by Anthony Zhang.
+
 - Issue #29354: Fixed inspect.getargs() for parameters which are cell
   variables.