bpo-35504: Fix segfaults and SystemErrors when deleting certain attrs. (GH-11175)
(cherry picked from commit 842acaab13
)
Co-authored-by: Zackery Spytz <zspytz@gmail.com>
This commit is contained in:
parent
c367d52a74
commit
cb272843f2
|
@ -54,6 +54,13 @@ class StringArrayTestCase(unittest.TestCase):
|
||||||
## print BUF.from_param(c_char_p("python"))
|
## print BUF.from_param(c_char_p("python"))
|
||||||
## print BUF.from_param(BUF(*"pyth"))
|
## print BUF.from_param(BUF(*"pyth"))
|
||||||
|
|
||||||
|
def test_del_segfault(self):
|
||||||
|
BUF = c_char * 4
|
||||||
|
buf = BUF()
|
||||||
|
with self.assertRaises(AttributeError):
|
||||||
|
del buf.raw
|
||||||
|
|
||||||
|
|
||||||
@need_symbol('c_wchar')
|
@need_symbol('c_wchar')
|
||||||
class WStringArrayTestCase(unittest.TestCase):
|
class WStringArrayTestCase(unittest.TestCase):
|
||||||
def test(self):
|
def test(self):
|
||||||
|
|
|
@ -379,6 +379,10 @@ class RegressionTests(unittest.TestCase):
|
||||||
del ref
|
del ref
|
||||||
support.gc_collect()
|
support.gc_collect()
|
||||||
|
|
||||||
|
def CheckDelIsolation_levelSegfault(self):
|
||||||
|
with self.assertRaises(AttributeError):
|
||||||
|
del self.con.isolation_level
|
||||||
|
|
||||||
|
|
||||||
class UnhashableFunc:
|
class UnhashableFunc:
|
||||||
__hash__ = None
|
__hash__ = None
|
||||||
|
|
|
@ -277,6 +277,11 @@ class TestBase:
|
||||||
writer = self.writer(stream)
|
writer = self.writer(stream)
|
||||||
writer.reset()
|
writer.reset()
|
||||||
|
|
||||||
|
def test_incrementalencoder_del_segfault(self):
|
||||||
|
e = self.incrementalencoder()
|
||||||
|
with self.assertRaises(AttributeError):
|
||||||
|
del e.errors
|
||||||
|
|
||||||
|
|
||||||
class TestBase_Mapping(unittest.TestCase):
|
class TestBase_Mapping(unittest.TestCase):
|
||||||
pass_enctest = []
|
pass_enctest = []
|
||||||
|
|
|
@ -566,6 +566,13 @@ class CFutureTests(BaseFutureTests, test_utils.TestCase):
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
cls = None
|
cls = None
|
||||||
|
|
||||||
|
def test_future_del_segfault(self):
|
||||||
|
fut = self._new_future(loop=self.loop)
|
||||||
|
with self.assertRaises(AttributeError):
|
||||||
|
del fut._asyncio_future_blocking
|
||||||
|
with self.assertRaises(AttributeError):
|
||||||
|
del fut._log_traceback
|
||||||
|
|
||||||
|
|
||||||
@unittest.skipUnless(hasattr(futures, '_CFuture'),
|
@unittest.skipUnless(hasattr(futures, '_CFuture'),
|
||||||
'requires the C _asyncio module')
|
'requires the C _asyncio module')
|
||||||
|
|
|
@ -2512,6 +2512,15 @@ class CTask_CFuture_Tests(BaseTaskTests, SetMethodsTest,
|
||||||
self.loop.run_until_complete(task)
|
self.loop.run_until_complete(task)
|
||||||
self.assertAlmostEqual(gettotalrefcount() - refs_before, 0, delta=10)
|
self.assertAlmostEqual(gettotalrefcount() - refs_before, 0, delta=10)
|
||||||
|
|
||||||
|
def test_del__log_destroy_pending_segfault(self):
|
||||||
|
@asyncio.coroutine
|
||||||
|
def coro():
|
||||||
|
pass
|
||||||
|
task = self.new_task(self.loop, coro())
|
||||||
|
self.loop.run_until_complete(task)
|
||||||
|
with self.assertRaises(AttributeError):
|
||||||
|
del task._log_destroy_pending
|
||||||
|
|
||||||
|
|
||||||
@unittest.skipUnless(hasattr(futures, '_CFuture') and
|
@unittest.skipUnless(hasattr(futures, '_CFuture') and
|
||||||
hasattr(tasks, '_CTask'),
|
hasattr(tasks, '_CTask'),
|
||||||
|
|
|
@ -109,10 +109,7 @@ class ClearTest(unittest.TestCase):
|
||||||
self.assertIs(None, wr())
|
self.assertIs(None, wr())
|
||||||
|
|
||||||
|
|
||||||
class FrameLocalsTest(unittest.TestCase):
|
class FrameAttrsTest(unittest.TestCase):
|
||||||
"""
|
|
||||||
Tests for the .f_locals attribute.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def make_frames(self):
|
def make_frames(self):
|
||||||
def outer():
|
def outer():
|
||||||
|
@ -159,6 +156,11 @@ class FrameLocalsTest(unittest.TestCase):
|
||||||
self.assertEqual(outer.f_locals, {})
|
self.assertEqual(outer.f_locals, {})
|
||||||
self.assertEqual(inner.f_locals, {})
|
self.assertEqual(inner.f_locals, {})
|
||||||
|
|
||||||
|
def test_f_lineno_del_segfault(self):
|
||||||
|
f, _, _ = self.make_frames()
|
||||||
|
with self.assertRaises(AttributeError):
|
||||||
|
del f.f_lineno
|
||||||
|
|
||||||
|
|
||||||
class ReprTest(unittest.TestCase):
|
class ReprTest(unittest.TestCase):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -3635,6 +3635,11 @@ class CTextIOWrapperTest(TextIOWrapperTest):
|
||||||
t2.buddy = t1
|
t2.buddy = t1
|
||||||
support.gc_collect()
|
support.gc_collect()
|
||||||
|
|
||||||
|
def test_del__CHUNK_SIZE_SystemError(self):
|
||||||
|
t = self.TextIOWrapper(self.BytesIO(), encoding='ascii')
|
||||||
|
with self.assertRaises(AttributeError):
|
||||||
|
del t._CHUNK_SIZE
|
||||||
|
|
||||||
|
|
||||||
class PyTextIOWrapperTest(TextIOWrapperTest):
|
class PyTextIOWrapperTest(TextIOWrapperTest):
|
||||||
io = pyio
|
io = pyio
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
Fix segfaults and :exc:`SystemError`\ s when deleting certain attributes.
|
||||||
|
Patch by Zackery Spytz.
|
|
@ -1110,6 +1110,10 @@ FutureObj_set_blocking(FutureObj *fut, PyObject *val, void *Py_UNUSED(ignored))
|
||||||
if (future_ensure_alive(fut)) {
|
if (future_ensure_alive(fut)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
if (val == NULL) {
|
||||||
|
PyErr_SetString(PyExc_AttributeError, "cannot delete attribute");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
int is_true = PyObject_IsTrue(val);
|
int is_true = PyObject_IsTrue(val);
|
||||||
if (is_true < 0) {
|
if (is_true < 0) {
|
||||||
|
@ -1134,6 +1138,10 @@ FutureObj_get_log_traceback(FutureObj *fut, void *Py_UNUSED(ignored))
|
||||||
static int
|
static int
|
||||||
FutureObj_set_log_traceback(FutureObj *fut, PyObject *val, void *Py_UNUSED(ignored))
|
FutureObj_set_log_traceback(FutureObj *fut, PyObject *val, void *Py_UNUSED(ignored))
|
||||||
{
|
{
|
||||||
|
if (val == NULL) {
|
||||||
|
PyErr_SetString(PyExc_AttributeError, "cannot delete attribute");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
int is_true = PyObject_IsTrue(val);
|
int is_true = PyObject_IsTrue(val);
|
||||||
if (is_true < 0) {
|
if (is_true < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -2008,6 +2016,10 @@ TaskObj_get_log_destroy_pending(TaskObj *task, void *Py_UNUSED(ignored))
|
||||||
static int
|
static int
|
||||||
TaskObj_set_log_destroy_pending(TaskObj *task, PyObject *val, void *Py_UNUSED(ignored))
|
TaskObj_set_log_destroy_pending(TaskObj *task, PyObject *val, void *Py_UNUSED(ignored))
|
||||||
{
|
{
|
||||||
|
if (val == NULL) {
|
||||||
|
PyErr_SetString(PyExc_AttributeError, "cannot delete attribute");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
int is_true = PyObject_IsTrue(val);
|
int is_true = PyObject_IsTrue(val);
|
||||||
if (is_true < 0) {
|
if (is_true < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -1171,6 +1171,10 @@ CharArray_set_raw(CDataObject *self, PyObject *value, void *Py_UNUSED(ignored))
|
||||||
Py_ssize_t size;
|
Py_ssize_t size;
|
||||||
Py_buffer view;
|
Py_buffer view;
|
||||||
|
|
||||||
|
if (value == NULL) {
|
||||||
|
PyErr_SetString(PyExc_AttributeError, "cannot delete attribute");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
if (PyObject_GetBuffer(value, &view, PyBUF_SIMPLE) < 0)
|
if (PyObject_GetBuffer(value, &view, PyBUF_SIMPLE) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
size = view.len;
|
size = view.len;
|
||||||
|
|
|
@ -3049,6 +3049,10 @@ textiowrapper_chunk_size_set(textio *self, PyObject *arg, void *context)
|
||||||
{
|
{
|
||||||
Py_ssize_t n;
|
Py_ssize_t n;
|
||||||
CHECK_ATTACHED_INT(self);
|
CHECK_ATTACHED_INT(self);
|
||||||
|
if (arg == NULL) {
|
||||||
|
PyErr_SetString(PyExc_AttributeError, "cannot delete attribute");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
n = PyNumber_AsSsize_t(arg, PyExc_ValueError);
|
n = PyNumber_AsSsize_t(arg, PyExc_ValueError);
|
||||||
if (n == -1 && PyErr_Occurred())
|
if (n == -1 && PyErr_Occurred())
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -1138,6 +1138,10 @@ static PyObject* pysqlite_connection_get_in_transaction(pysqlite_Connection* sel
|
||||||
static int
|
static int
|
||||||
pysqlite_connection_set_isolation_level(pysqlite_Connection* self, PyObject* isolation_level, void *Py_UNUSED(ignored))
|
pysqlite_connection_set_isolation_level(pysqlite_Connection* self, PyObject* isolation_level, void *Py_UNUSED(ignored))
|
||||||
{
|
{
|
||||||
|
if (isolation_level == NULL) {
|
||||||
|
PyErr_SetString(PyExc_AttributeError, "cannot delete attribute");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
if (isolation_level == Py_None) {
|
if (isolation_level == Py_None) {
|
||||||
PyObject *res = pysqlite_connection_commit(self, NULL);
|
PyObject *res = pysqlite_connection_commit(self, NULL);
|
||||||
if (!res) {
|
if (!res) {
|
||||||
|
|
|
@ -3626,6 +3626,10 @@ static int
|
||||||
set_post_handshake_auth(PySSLContext *self, PyObject *arg, void *c) {
|
set_post_handshake_auth(PySSLContext *self, PyObject *arg, void *c) {
|
||||||
int (*verify_cb)(int, X509_STORE_CTX *) = NULL;
|
int (*verify_cb)(int, X509_STORE_CTX *) = NULL;
|
||||||
int mode = SSL_CTX_get_verify_mode(self->ctx);
|
int mode = SSL_CTX_get_verify_mode(self->ctx);
|
||||||
|
if (arg == NULL) {
|
||||||
|
PyErr_SetString(PyExc_AttributeError, "cannot delete attribute");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
int pha = PyObject_IsTrue(arg);
|
int pha = PyObject_IsTrue(arg);
|
||||||
|
|
||||||
if (pha == -1) {
|
if (pha == -1) {
|
||||||
|
|
|
@ -133,6 +133,10 @@ codecctx_errors_set(MultibyteStatefulCodecContext *self, PyObject *value,
|
||||||
PyObject *cb;
|
PyObject *cb;
|
||||||
const char *str;
|
const char *str;
|
||||||
|
|
||||||
|
if (value == NULL) {
|
||||||
|
PyErr_SetString(PyExc_AttributeError, "cannot delete attribute");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
if (!PyUnicode_Check(value)) {
|
if (!PyUnicode_Check(value)) {
|
||||||
PyErr_SetString(PyExc_TypeError, "errors must be a string");
|
PyErr_SetString(PyExc_TypeError, "errors must be a string");
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -90,6 +90,10 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno, void *Py_UNUSED(ignore
|
||||||
int blockstack_top = 0; /* (ditto) */
|
int blockstack_top = 0; /* (ditto) */
|
||||||
unsigned char setup_op = 0; /* (ditto) */
|
unsigned char setup_op = 0; /* (ditto) */
|
||||||
|
|
||||||
|
if (p_new_lineno == NULL) {
|
||||||
|
PyErr_SetString(PyExc_AttributeError, "cannot delete attribute");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
/* f_lineno must be an integer. */
|
/* f_lineno must be an integer. */
|
||||||
if (!PyLong_CheckExact(p_new_lineno)) {
|
if (!PyLong_CheckExact(p_new_lineno)) {
|
||||||
PyErr_SetString(PyExc_ValueError,
|
PyErr_SetString(PyExc_ValueError,
|
||||||
|
|
Loading…
Reference in New Issue