Skip to content

Commit 02eb4b0

Browse files
authored
bpo-29110: Fix file object leak in aifc.open (pythonGH-356)
1 parent c8e2021 commit 02eb4b0

File tree

3 files changed

+30
-4
lines changed

3 files changed

+30
-4
lines changed

Lib/aifc.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,8 @@ class Aifc_read:
288288
# _ssnd_chunk -- instantiation of a chunk class for the SSND chunk
289289
# _framesize -- size of one frame in the file
290290

291+
_file = None # Set here since __del__ checks it
292+
291293
def initfp(self, file):
292294
self._version = 0
293295
self._decomp = None
@@ -341,10 +343,16 @@ def initfp(self, file):
341343
self._decomp.SetParams(params)
342344

343345
def __init__(self, f):
344-
if type(f) == type(''):
346+
if isinstance(f, basestring):
345347
f = __builtin__.open(f, 'rb')
346-
# else, assume it is an open file object already
347-
self.initfp(f)
348+
try:
349+
self.initfp(f)
350+
except:
351+
f.close()
352+
raise
353+
else:
354+
# assume it is an open file object already
355+
self.initfp(f)
348356

349357
#
350358
# User visible methods.
@@ -562,8 +570,10 @@ class Aifc_write:
562570
# _datalength -- the size of the audio samples written to the header
563571
# _datawritten -- the size of the audio samples actually written
564572

573+
_file = None # Set here since __del__ checks it
574+
565575
def __init__(self, f):
566-
if type(f) == type(''):
576+
if isinstance(f, basestring):
567577
filename = f
568578
f = __builtin__.open(f, 'wb')
569579
else:

Lib/test/test_aifc.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,18 @@ def test_skipunknown(self):
129129
#This file contains chunk types aifc doesn't recognize.
130130
self.f = aifc.open(findfile('Sine-1000Hz-300ms.aif'))
131131

132+
def test_close_opened_files_on_error(self):
133+
non_aifc_file = findfile('pluck-pcm8.wav', subdir='audiodata')
134+
135+
class Aifc(aifc.Aifc_read):
136+
def __init__(self):
137+
pass
138+
139+
a = Aifc()
140+
with self.assertRaises(aifc.Error):
141+
aifc.Aifc_read.__init__(a, non_aifc_file)
142+
self.assertTrue(a._file.closed)
143+
132144
def test_write_markers_values(self):
133145
fout = aifc.open(io.BytesIO(), 'wb')
134146
self.assertEqual(fout.getmarkers(), None)

Misc/NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ Extension Modules
3636
Library
3737
-------
3838

39+
- bpo-29110: Fix file object leak in aifc.open() when file is given as a
40+
filesystem path and is not in valid AIFF format.
41+
Original patch by Anthony Zhang.
42+
3943
- Issue #29354: Fixed inspect.getargs() for parameters which are cell
4044
variables.
4145

0 commit comments

Comments
 (0)