bpo-28963: Fix out of bound iteration in asyncio.Future.remove_done_callback/C (#408)

This commit is contained in:
Yury Selivanov 2017-03-02 23:46:56 -05:00 committed by Yury Selivanov
parent 2ef08d3be7
commit d8b72e4a06
3 changed files with 33 additions and 1 deletions

View File

@ -569,6 +569,35 @@ class BaseFutureDoneCallbackTests():
self.assertEqual(bag, [2])
self.assertEqual(f.result(), 'foo')
def test_remove_done_callbacks_list_mutation(self):
# see http://bugs.python.org/issue28963 for details
fut = self._new_future()
fut.add_done_callback(str)
for _ in range(63):
fut.add_done_callback(id)
class evil:
def __eq__(self, other):
fut.remove_done_callback(id)
return False
fut.remove_done_callback(evil())
def test_schedule_callbacks_list_mutation(self):
# see http://bugs.python.org/issue28963 for details
def mut(f):
f.remove_done_callback(str)
fut = self._new_future()
fut.add_done_callback(mut)
fut.add_done_callback(str)
fut.add_done_callback(str)
fut.set_result(1)
test_utils.run_briefly(self.loop)
@unittest.skipUnless(hasattr(futures, '_CFuture'),
'requires the C _asyncio module')

View File

@ -261,6 +261,9 @@ Extension Modules
Library
-------
- bpo-28963: Fix out of bound iteration in asyncio.Future.remove_done_callback
implemented in C.
- bpo-29704: asyncio.subprocess.SubprocessStreamProtocol no longer closes before
all pipes are closed.

View File

@ -521,7 +521,7 @@ _asyncio_Future_remove_done_callback(FutureObj *self, PyObject *fn)
return NULL;
}
for (i = 0; i < len; i++) {
for (i = 0; i < PyList_GET_SIZE(self->fut_callbacks); i++) {
int ret;
PyObject *item = PyList_GET_ITEM(self->fut_callbacks, i);