[Python-checkins] cpython (2.7): Closes #19878: Fix segfault in bz2 module.

nadeem.vawda python-checkins at python.org
Sun Dec 8 15:49:32 CET 2013


http://hg.python.org/cpython/rev/55a748f6e396
changeset:   87832:55a748f6e396
branch:      2.7
parent:      87797:9bf55766d935
user:        Nadeem Vawda <nadeem.vawda at gmail.com>
date:        Sun Dec 08 15:31:50 2013 +0100
summary:
  Closes #19878: Fix segfault in bz2 module.

Initial patch by Vajrasky Kok.

files:
  Lib/test/test_bz2.py |  12 ++++++++++++
  Misc/NEWS            |   3 +++
  Modules/bz2module.c  |  17 ++++++++++-------
  3 files changed, 25 insertions(+), 7 deletions(-)


diff --git a/Lib/test/test_bz2.py b/Lib/test/test_bz2.py
--- a/Lib/test/test_bz2.py
+++ b/Lib/test/test_bz2.py
@@ -325,6 +325,18 @@
             self.assertRaises(ValueError, f.readline)
             self.assertRaises(ValueError, f.readlines)
 
+    def testInitNonExistentFile(self):
+        # Issue #19878: Should not segfault when __init__ with non-existent
+        # file for the second time.
+        self.createTempFile()
+        # Test close():
+        with BZ2File(self.filename, "wb") as f:
+            self.assertRaises(IOError, f.__init__, "non-existent-file")
+        # Test object deallocation without call to close():
+        f = bz2.BZ2File(self.filename)
+        self.assertRaises(IOError, f.__init__, "non-existent-file")
+        del f
+
 class BZ2CompressorTest(BaseTest):
     def testCompress(self):
         # "Test BZ2Compressor.compress()/flush()"
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -15,6 +15,9 @@
 Library
 -------
 
+- Issue #19878: Fix segfault in bz2 module after calling __init__ twice with
+  non-existent filename. Initial patch by Vajrasky Kok.
+
 - Issue #16373: Prevent infinite recursion for ABC Set class comparisons.
 
 - Issue #19138: doctest's IGNORE_EXCEPTION_DETAIL now allows a match when
diff --git a/Modules/bz2module.c b/Modules/bz2module.c
--- a/Modules/bz2module.c
+++ b/Modules/bz2module.c
@@ -1206,12 +1206,16 @@
                              0, NULL, NULL);
             break;
     }
-    if (self->fp) {
-        PyFile_DecUseCount((PyFileObject *)self->file);
-        self->fp = NULL;
+    if (self->file) {
+        if (self->fp)
+            PyFile_DecUseCount((PyFileObject *)self->file);
+        ret = PyObject_CallMethod(self->file, "close", NULL);
+    } else {
+        Py_INCREF(Py_None);
+        ret = Py_None;
     }
+    self->fp = NULL;
     self->mode = MODE_CLOSED;
-    ret = PyObject_CallMethod(self->file, "close", NULL);
     if (bzerror != BZ_OK) {
         Util_CatchBZ2Error(bzerror);
         Py_XDECREF(ret);
@@ -1479,10 +1483,9 @@
                              0, NULL, NULL);
             break;
     }
-    if (self->fp) {
+    if (self->fp != NULL && self->file != NULL)
         PyFile_DecUseCount((PyFileObject *)self->file);
-        self->fp = NULL;
-    }
+    self->fp = NULL;
     Util_DropReadAhead(self);
     Py_XDECREF(self->file);
     Py_TYPE(self)->tp_free((PyObject *)self);

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list