]> granicus.if.org Git - python/commitdiff
Closes #19878: Fix segfault in bz2 module.
authorNadeem Vawda <nadeem.vawda@gmail.com>
Sun, 8 Dec 2013 14:31:50 +0000 (15:31 +0100)
committerNadeem Vawda <nadeem.vawda@gmail.com>
Sun, 8 Dec 2013 14:31:50 +0000 (15:31 +0100)
Initial patch by Vajrasky Kok.

Lib/test/test_bz2.py
Misc/NEWS
Modules/bz2module.c

index 127511466484da1f29475dfb60c209dae7f7df2b..a981d2800224f66689724ed04e4b5ccb41a9d298 100644 (file)
@@ -325,6 +325,18 @@ class BZ2FileTest(BaseTest):
             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()"
index 059f7bfe09955d5529dd7e188f141bb5f7aa4530..928a18ed262b52f67ce08f3430eb8b1d686d6d0e 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -15,6 +15,9 @@ Core and Builtins
 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
index 4083fdfb68bf2a536fb149dbb7ae96520270633e..e479777a1b34838988c46de408a66f0be058561d 100644 (file)
@@ -1206,12 +1206,16 @@ BZ2File_close(BZ2FileObject *self)
                              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 @@ BZ2File_dealloc(BZ2FileObject *self)
                              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);