]> granicus.if.org Git - python/commitdiff
Issue #25688: Fixed file leak in ElementTree.iterparse() raising an error.
authorSerhiy Storchaka <storchaka@gmail.com>
Mon, 23 Nov 2015 13:46:36 +0000 (15:46 +0200)
committerSerhiy Storchaka <storchaka@gmail.com>
Mon, 23 Nov 2015 13:46:36 +0000 (15:46 +0200)
Lib/xml/etree/ElementTree.py
Misc/NEWS

index 9f3e75d4a6f0d39c10c59911b438ccbcc05d5202..c6e3d396b19dd57411dc68e889e156eea238f8bc 100644 (file)
@@ -1198,9 +1198,14 @@ def iterparse(source, events=None, parser=None):
     if not hasattr(source, "read"):
         source = open(source, "rb")
         close_source = True
-    if not parser:
-        parser = XMLParser(target=TreeBuilder())
-    return _IterParseIterator(source, events, parser, close_source)
+    try:
+        if not parser:
+            parser = XMLParser(target=TreeBuilder())
+        return _IterParseIterator(source, events, parser, close_source)
+    except:
+        if close_source:
+            source.close()
+        raise
 
 class _IterParseIterator(object):
 
@@ -1252,34 +1257,40 @@ class _IterParseIterator(object):
                 raise ValueError("unknown event %r" % event)
 
     def next(self):
-        while 1:
-            try:
-                item = self._events[self._index]
-                self._index += 1
-                return item
-            except IndexError:
-                pass
-            if self._error:
-                e = self._error
-                self._error = None
-                raise e
-            if self._parser is None:
-                self.root = self._root
-                if self._close_file:
-                    self._file.close()
-                raise StopIteration
-            # load event buffer
-            del self._events[:]
-            self._index = 0
-            data = self._file.read(16384)
-            if data:
+        try:
+            while 1:
                 try:
-                    self._parser.feed(data)
-                except SyntaxError as exc:
-                    self._error = exc
-            else:
-                self._root = self._parser.close()
-                self._parser = None
+                    item = self._events[self._index]
+                    self._index += 1
+                    return item
+                except IndexError:
+                    pass
+                if self._error:
+                    e = self._error
+                    self._error = None
+                    raise e
+                if self._parser is None:
+                    self.root = self._root
+                    break
+                # load event buffer
+                del self._events[:]
+                self._index = 0
+                data = self._file.read(16384)
+                if data:
+                    try:
+                        self._parser.feed(data)
+                    except SyntaxError as exc:
+                        self._error = exc
+                else:
+                    self._root = self._parser.close()
+                    self._parser = None
+        except:
+            if self._close_file:
+                self._file.close()
+            raise
+        if self._close_file:
+            self._file.close()
+        raise StopIteration
 
     def __iter__(self):
         return self
index ec5c37831467c56587ead2497f4ac28bb89fc3a6..25100899cb8664dc5bba58c8efadf8d9cb64e228 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -13,8 +13,11 @@ Core and Builtins
 Library
 -------
 
+- Issue #25688: Fixed file leak in ElementTree.iterparse() raising an error.
+
 - Issue #23914: Fixed SystemError raised by CPickle unpickler on broken data.
 
+
 What's New in Python 2.7.11?
 ============================