Commit 337c50b8 authored by Nadeem Vawda's avatar Nadeem Vawda

Closes #19878: Fix segfault in bz2 module.

Initial patch by Vajrasky Kok.
parent 7c573857
...@@ -325,6 +325,18 @@ class BZ2FileTest(BaseTest): ...@@ -325,6 +325,18 @@ class BZ2FileTest(BaseTest):
self.assertRaises(ValueError, f.readline) self.assertRaises(ValueError, f.readline)
self.assertRaises(ValueError, f.readlines) 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): class BZ2CompressorTest(BaseTest):
def testCompress(self): def testCompress(self):
# "Test BZ2Compressor.compress()/flush()" # "Test BZ2Compressor.compress()/flush()"
......
...@@ -15,6 +15,9 @@ Core and Builtins ...@@ -15,6 +15,9 @@ Core and Builtins
Library 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 #16373: Prevent infinite recursion for ABC Set class comparisons.
- Issue #19138: doctest's IGNORE_EXCEPTION_DETAIL now allows a match when - Issue #19138: doctest's IGNORE_EXCEPTION_DETAIL now allows a match when
......
...@@ -1206,12 +1206,16 @@ BZ2File_close(BZ2FileObject *self) ...@@ -1206,12 +1206,16 @@ BZ2File_close(BZ2FileObject *self)
0, NULL, NULL); 0, NULL, NULL);
break; break;
} }
if (self->fp) { if (self->file) {
PyFile_DecUseCount((PyFileObject *)self->file); if (self->fp)
self->fp = NULL; 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; self->mode = MODE_CLOSED;
ret = PyObject_CallMethod(self->file, "close", NULL);
if (bzerror != BZ_OK) { if (bzerror != BZ_OK) {
Util_CatchBZ2Error(bzerror); Util_CatchBZ2Error(bzerror);
Py_XDECREF(ret); Py_XDECREF(ret);
...@@ -1479,10 +1483,9 @@ BZ2File_dealloc(BZ2FileObject *self) ...@@ -1479,10 +1483,9 @@ BZ2File_dealloc(BZ2FileObject *self)
0, NULL, NULL); 0, NULL, NULL);
break; break;
} }
if (self->fp) { if (self->fp != NULL && self->file != NULL)
PyFile_DecUseCount((PyFileObject *)self->file); PyFile_DecUseCount((PyFileObject *)self->file);
self->fp = NULL; self->fp = NULL;
}
Util_DropReadAhead(self); Util_DropReadAhead(self);
Py_XDECREF(self->file); Py_XDECREF(self->file);
Py_TYPE(self)->tp_free((PyObject *)self); Py_TYPE(self)->tp_free((PyObject *)self);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment