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(BUF(*"pyth"))
|
||||
|
||||
def test_del_segfault(self):
|
||||
BUF = c_char * 4
|
||||
buf = BUF()
|
||||
with self.assertRaises(AttributeError):
|
||||
del buf.raw
|
||||
|
||||
|
||||
@need_symbol('c_wchar')
|
||||
class WStringArrayTestCase(unittest.TestCase):
|
||||
def test(self):
|
||||
|
|
|
@ -379,6 +379,10 @@ class RegressionTests(unittest.TestCase):
|
|||
del ref
|
||||
support.gc_collect()
|
||||
|
||||
def CheckDelIsolation_levelSegfault(self):
|
||||
with self.assertRaises(AttributeError):
|
||||
del self.con.isolation_level
|
||||
|
||||
|
||||
class UnhashableFunc:
|
||||
__hash__ = None
|
||||
|
|
|
@ -277,6 +277,11 @@ class TestBase:
|
|||
writer = self.writer(stream)
|
||||
writer.reset()
|
||||
|
||||
def test_incrementalencoder_del_segfault(self):
|
||||
e = self.incrementalencoder()
|
||||
with self.assertRaises(AttributeError):
|
||||
del e.errors
|
||||
|
||||
|
||||
class TestBase_Mapping(unittest.TestCase):
|
||||
pass_enctest = []
|
||||
|
|
|
@ -566,6 +566,13 @@ class CFutureTests(BaseFutureTests, test_utils.TestCase):
|
|||
except AttributeError:
|
||||
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'),
|
||||
'requires the C _asyncio module')
|
||||
|
|
|
@ -2512,6 +2512,15 @@ class CTask_CFuture_Tests(BaseTaskTests, SetMethodsTest,
|
|||
self.loop.run_until_complete(task)
|
||||
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
|
||||
hasattr(tasks, '_CTask'),
|
||||
|
|
|
@ -109,10 +109,7 @@ class ClearTest(unittest.TestCase):
|
|||
self.assertIs(None, wr())
|
||||
|
||||
|
||||
class FrameLocalsTest(unittest.TestCase):
|
||||
"""
|
||||
Tests for the .f_locals attribute.
|
||||
"""
|
||||
class FrameAttrsTest(unittest.TestCase):
|
||||
|
||||
def make_frames(self):
|
||||
def outer():
|
||||
|
@ -159,6 +156,11 @@ class FrameLocalsTest(unittest.TestCase):
|
|||
self.assertEqual(outer.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):
|
||||
"""
|
||||
|
|
|
@ -3635,6 +3635,11 @@ class CTextIOWrapperTest(TextIOWrapperTest):
|
|||
t2.buddy = t1
|
||||
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):
|
||||
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)) {
|
||||
return -1;
|
||||
}
|
||||
if (val == NULL) {
|
||||
PyErr_SetString(PyExc_AttributeError, "cannot delete attribute");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int is_true = PyObject_IsTrue(val);
|
||||
if (is_true < 0) {
|
||||
|
@ -1134,6 +1138,10 @@ FutureObj_get_log_traceback(FutureObj *fut, void *Py_UNUSED(ignored))
|
|||
static int
|
||||
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);
|
||||
if (is_true < 0) {
|
||||
return -1;
|
||||
|
@ -2008,6 +2016,10 @@ TaskObj_get_log_destroy_pending(TaskObj *task, void *Py_UNUSED(ignored))
|
|||
static int
|
||||
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);
|
||||
if (is_true < 0) {
|
||||
return -1;
|
||||
|
|
|
@ -1171,6 +1171,10 @@ CharArray_set_raw(CDataObject *self, PyObject *value, void *Py_UNUSED(ignored))
|
|||
Py_ssize_t size;
|
||||
Py_buffer view;
|
||||
|
||||
if (value == NULL) {
|
||||
PyErr_SetString(PyExc_AttributeError, "cannot delete attribute");
|
||||
return -1;
|
||||
}
|
||||
if (PyObject_GetBuffer(value, &view, PyBUF_SIMPLE) < 0)
|
||||
return -1;
|
||||
size = view.len;
|
||||
|
|
|
@ -3049,6 +3049,10 @@ textiowrapper_chunk_size_set(textio *self, PyObject *arg, void *context)
|
|||
{
|
||||
Py_ssize_t n;
|
||||
CHECK_ATTACHED_INT(self);
|
||||
if (arg == NULL) {
|
||||
PyErr_SetString(PyExc_AttributeError, "cannot delete attribute");
|
||||
return -1;
|
||||
}
|
||||
n = PyNumber_AsSsize_t(arg, PyExc_ValueError);
|
||||
if (n == -1 && PyErr_Occurred())
|
||||
return -1;
|
||||
|
|
|
@ -1138,6 +1138,10 @@ static PyObject* pysqlite_connection_get_in_transaction(pysqlite_Connection* sel
|
|||
static int
|
||||
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) {
|
||||
PyObject *res = pysqlite_connection_commit(self, NULL);
|
||||
if (!res) {
|
||||
|
|
|
@ -3626,6 +3626,10 @@ static int
|
|||
set_post_handshake_auth(PySSLContext *self, PyObject *arg, void *c) {
|
||||
int (*verify_cb)(int, X509_STORE_CTX *) = NULL;
|
||||
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);
|
||||
|
||||
if (pha == -1) {
|
||||
|
|
|
@ -133,6 +133,10 @@ codecctx_errors_set(MultibyteStatefulCodecContext *self, PyObject *value,
|
|||
PyObject *cb;
|
||||
const char *str;
|
||||
|
||||
if (value == NULL) {
|
||||
PyErr_SetString(PyExc_AttributeError, "cannot delete attribute");
|
||||
return -1;
|
||||
}
|
||||
if (!PyUnicode_Check(value)) {
|
||||
PyErr_SetString(PyExc_TypeError, "errors must be a string");
|
||||
return -1;
|
||||
|
|
|
@ -90,6 +90,10 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno, void *Py_UNUSED(ignore
|
|||
int blockstack_top = 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. */
|
||||
if (!PyLong_CheckExact(p_new_lineno)) {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
|
|
Loading…
Reference in New Issue