Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 03f68b6

Browse files
Uberimethane
authored andcommitted
bpo-29110: Fix file object leak in aifc.open when given invalid AIFF file. (GH-162)
1 parent 0899b98 commit 03f68b6

File tree

3 files changed

+33
-13
lines changed

3 files changed

+33
-13
lines changed

Lib/aifc.py

+21-12
Original file line numberDiff line numberDiff line change
@@ -344,9 +344,15 @@ def initfp(self, file):
344344

345345
def __init__(self, f):
346346
if isinstance(f, str):
347-
f = builtins.open(f, 'rb')
348-
# else, assume it is an open file object already
349-
self.initfp(f)
347+
file_object = builtins.open(f, 'rb')
348+
try:
349+
self.initfp(file_object)
350+
except:
351+
file_object.close()
352+
raise
353+
else:
354+
# assume it is an open file object already
355+
self.initfp(f)
350356

351357
def __enter__(self):
352358
return self
@@ -543,16 +549,19 @@ class Aifc_write:
543549

544550
def __init__(self, f):
545551
if isinstance(f, str):
546-
filename = f
547-
f = builtins.open(f, 'wb')
548-
else:
549-
# else, assume it is an open file object already
550-
filename = '???'
551-
self.initfp(f)
552-
if filename[-5:] == '.aiff':
553-
self._aifc = 0
552+
file_object = builtins.open(f, 'wb')
553+
try:
554+
self.initfp(file_object)
555+
except:
556+
file_object.close()
557+
raise
558+
559+
# treat .aiff file extensions as non-compressed audio
560+
if f.endswith('.aiff'):
561+
self._aifc = 0
554562
else:
555-
self._aifc = 1
563+
# assume it is an open file object already
564+
self.initfp(f)
556565

557566
def initfp(self, file):
558567
self._file = file

Lib/test/test_aifc.py

+9-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from test.support import findfile, TESTFN, unlink
1+
from test.support import check_no_resource_warning, findfile, TESTFN, unlink
22
import unittest
33
from test import audiotests
44
from audioop import byteswap
@@ -149,6 +149,14 @@ def test_skipunknown(self):
149149
#This file contains chunk types aifc doesn't recognize.
150150
self.f = aifc.open(findfile('Sine-1000Hz-300ms.aif'))
151151

152+
def test_close_opened_files_on_error(self):
153+
non_aifc_file = findfile('pluck-pcm8.wav', subdir='audiodata')
154+
with check_no_resource_warning(self):
155+
with self.assertRaises(aifc.Error):
156+
# Try opening a non-AIFC file, with the expectation that
157+
# `aifc.open` will fail (without raising a ResourceWarning)
158+
f = self.f = aifc.open(non_aifc_file, 'rb')
159+
152160
def test_params_added(self):
153161
f = self.f = aifc.open(TESTFN, 'wb')
154162
f.aiff()

Misc/NEWS

+3
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,9 @@ Library
242242
- bpo-29532: Altering a kwarg dictionary passed to functools.partial()
243243
no longer affects a partial object after creation.
244244

245+
- bpo-29110: Fix file object leak in aifc.open() when file is given as a
246+
filesystem path and is not in valid AIFF format. Patch by Anthony Zhang.
247+
245248
- bpo-22807: Add uuid.SafeUUID and uuid.UUID.is_safe to relay information from
246249
the platform about whether generated UUIDs are generated with a
247250
multiprocessing safe method.

0 commit comments

Comments
 (0)