From 1adbacfd1c80f4f724c5d515e48a518d0b1be2dd Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sat, 25 Jan 2014 19:42:27 +0200 Subject: [PATCH] Issue #20331: Fixed possible FD leaks in various modules: SimpleHTTPServer, imghdr, mailcap, mimetypes, xml.etree. --- Lib/SimpleHTTPServer.py | 24 +++++++++++++++--------- Lib/imghdr.py | 20 +++++++++----------- Lib/mailcap.py | 4 ++-- Lib/mimetypes.py | 7 ++++--- Lib/xml/etree/ElementInclude.py | 15 +++++++-------- 5 files changed, 37 insertions(+), 33 deletions(-) diff --git a/Lib/SimpleHTTPServer.py b/Lib/SimpleHTTPServer.py index 1a172968658..d497e1e8cc7 100644 --- a/Lib/SimpleHTTPServer.py +++ b/Lib/SimpleHTTPServer.py @@ -43,8 +43,10 @@ class SimpleHTTPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): """Serve a GET request.""" f = self.send_head() if f: - self.copyfile(f, self.wfile) - f.close() + try: + self.copyfile(f, self.wfile) + finally: + f.close() def do_HEAD(self): """Serve a HEAD request.""" @@ -88,13 +90,17 @@ class SimpleHTTPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): except IOError: self.send_error(404, "File not found") return None - self.send_response(200) - self.send_header("Content-type", ctype) - fs = os.fstat(f.fileno()) - self.send_header("Content-Length", str(fs[6])) - self.send_header("Last-Modified", self.date_time_string(fs.st_mtime)) - self.end_headers() - return f + try: + self.send_response(200) + self.send_header("Content-type", ctype) + fs = os.fstat(f.fileno()) + self.send_header("Content-Length", str(fs[6])) + self.send_header("Last-Modified", self.date_time_string(fs.st_mtime)) + self.end_headers() + return f + except: + f.close() + raise def list_directory(self, path): """Helper to produce a directory listing (absent index.html). diff --git a/Lib/imghdr.py b/Lib/imghdr.py index 1683024cb72..fc864c3a2ee 100644 --- a/Lib/imghdr.py +++ b/Lib/imghdr.py @@ -7,18 +7,16 @@ __all__ = ["what"] #-------------------------# def what(file, h=None): - if h is None: - if isinstance(file, basestring): - f = open(file, 'rb') - h = f.read(32) - else: - location = file.tell() - h = file.read(32) - file.seek(location) - f = None - else: - f = None + f = None try: + if h is None: + if isinstance(file, basestring): + f = open(file, 'rb') + h = f.read(32) + else: + location = file.tell() + h = file.read(32) + file.seek(location) for tf in tests: res = tf(h, f) if res: diff --git a/Lib/mailcap.py b/Lib/mailcap.py index b2ddacd046d..04077ba0db2 100644 --- a/Lib/mailcap.py +++ b/Lib/mailcap.py @@ -22,8 +22,8 @@ def getcaps(): fp = open(mailcap, 'r') except IOError: continue - morecaps = readmailcapfile(fp) - fp.close() + with fp: + morecaps = readmailcapfile(fp) for key, value in morecaps.iteritems(): if not key in caps: caps[key] = value diff --git a/Lib/mimetypes.py b/Lib/mimetypes.py index 3dde4cd9380..f04f569dd55 100644 --- a/Lib/mimetypes.py +++ b/Lib/mimetypes.py @@ -373,9 +373,10 @@ def read_mime_types(file): f = open(file) except IOError: return None - db = MimeTypes() - db.readfp(f, True) - return db.types_map[True] + with f: + db = MimeTypes() + db.readfp(f, True) + return db.types_map[True] def _default_mime_types(): diff --git a/Lib/xml/etree/ElementInclude.py b/Lib/xml/etree/ElementInclude.py index 84fd7548b28..7e29119fa5f 100644 --- a/Lib/xml/etree/ElementInclude.py +++ b/Lib/xml/etree/ElementInclude.py @@ -75,14 +75,13 @@ class FatalIncludeError(SyntaxError): # @throws IOError If the loader fails to load the resource. def default_loader(href, parse, encoding=None): - file = open(href) - if parse == "xml": - data = ElementTree.parse(file).getroot() - else: - data = file.read() - if encoding: - data = data.decode(encoding) - file.close() + with open(href) as file: + if parse == "xml": + data = ElementTree.parse(file).getroot() + else: + data = file.read() + if encoding: + data = data.decode(encoding) return data ##