bpo-35504: Fix segfaults and SystemErrors when deleting certain attrs. (GH-11175)

This commit is contained in:
Zackery Spytz 2018-12-17 07:52:45 -07:00 committed by Serhiy Storchaka
parent 4db62e1158
commit 842acaab13
15 changed files with 81 additions and 4 deletions

View File

@ -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):

View File

@ -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

View File

@ -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 = []

View File

@ -570,6 +570,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')

View File

@ -2546,6 +2546,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'),

View File

@ -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):
"""

View File

@ -3663,6 +3663,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

View File

@ -0,0 +1,2 @@
Fix segfaults and :exc:`SystemError`\ s when deleting certain attributes.
Patch by Zackery Spytz.

View File

@ -1113,6 +1113,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) {
@ -1137,6 +1141,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;
@ -2015,6 +2023,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;

View File

@ -1191,6 +1191,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;

View File

@ -3042,6 +3042,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;

View File

@ -1161,6 +1161,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) {

View File

@ -3625,6 +3625,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) {

View File

@ -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;

View File

@ -105,6 +105,10 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno, void *Py_UNUSED(ignore
int blockstack[CO_MAXBLOCKS]; /* Walking the 'finally' blocks */
int blockstack_top = 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,