From: INADA Naoki Date: Tue, 28 Feb 2017 11:39:30 +0000 (+0900) Subject: bpo-29110: Fix file object leak in aifc.open (GH-356) X-Git-Tag: v2.7.14rc1~262 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=02eb4b0bd4a7d86cf5e40567aaa8710b00e079a4;p=python bpo-29110: Fix file object leak in aifc.open (GH-356) --- diff --git a/Lib/aifc.py b/Lib/aifc.py index c9a021ee9d..e6783277a4 100644 --- a/Lib/aifc.py +++ b/Lib/aifc.py @@ -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: diff --git a/Lib/test/test_aifc.py b/Lib/test/test_aifc.py index d4e9de595a..d1b7dd0432 100644 --- a/Lib/test/test_aifc.py +++ b/Lib/test/test_aifc.py @@ -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) diff --git a/Misc/NEWS b/Misc/NEWS index 5e4a3daeca..4523df5a93 100644 --- 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.