bpo-30828: Fix out of bounds write in `asyncio.CFuture.remove_done_callback() (#2569)
This commit is contained in:
parent
8207c17486
commit
833a3b0d37
|
@ -593,7 +593,7 @@ class BaseFutureDoneCallbackTests():
|
||||||
|
|
||||||
fut.remove_done_callback(evil())
|
fut.remove_done_callback(evil())
|
||||||
|
|
||||||
def test_schedule_callbacks_list_mutation(self):
|
def test_schedule_callbacks_list_mutation_1(self):
|
||||||
# see http://bugs.python.org/issue28963 for details
|
# see http://bugs.python.org/issue28963 for details
|
||||||
|
|
||||||
def mut(f):
|
def mut(f):
|
||||||
|
@ -606,6 +606,28 @@ class BaseFutureDoneCallbackTests():
|
||||||
fut.set_result(1)
|
fut.set_result(1)
|
||||||
test_utils.run_briefly(self.loop)
|
test_utils.run_briefly(self.loop)
|
||||||
|
|
||||||
|
def test_schedule_callbacks_list_mutation_2(self):
|
||||||
|
# see http://bugs.python.org/issue30828 for details
|
||||||
|
|
||||||
|
fut = self._new_future()
|
||||||
|
fut.add_done_callback(str)
|
||||||
|
|
||||||
|
for _ in range(63):
|
||||||
|
fut.add_done_callback(id)
|
||||||
|
|
||||||
|
max_extra_cbs = 100
|
||||||
|
extra_cbs = 0
|
||||||
|
|
||||||
|
class evil:
|
||||||
|
def __eq__(self, other):
|
||||||
|
nonlocal extra_cbs
|
||||||
|
extra_cbs += 1
|
||||||
|
if extra_cbs < max_extra_cbs:
|
||||||
|
fut.add_done_callback(id)
|
||||||
|
return False
|
||||||
|
|
||||||
|
fut.remove_done_callback(evil())
|
||||||
|
|
||||||
|
|
||||||
@unittest.skipUnless(hasattr(futures, '_CFuture'),
|
@unittest.skipUnless(hasattr(futures, '_CFuture'),
|
||||||
'requires the C _asyncio module')
|
'requires the C _asyncio module')
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Fix out of bounds write in `asyncio.CFuture.remove_done_callback()`.
|
|
@ -532,10 +532,17 @@ _asyncio_Future_remove_done_callback(FutureObj *self, PyObject *fn)
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
|
if (j < len) {
|
||||||
Py_INCREF(item);
|
Py_INCREF(item);
|
||||||
PyList_SET_ITEM(newlist, j, item);
|
PyList_SET_ITEM(newlist, j, item);
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
if (PyList_Append(newlist, item)) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PyList_SetSlice(newlist, j, len, NULL) < 0) {
|
if (PyList_SetSlice(newlist, j, len, NULL) < 0) {
|
||||||
|
|
Loading…
Reference in New Issue