[Python-checkins] [3.12] gh-105987: Fix reference counting issue in `_asyncio._swap_cur… (#106099)
kumaraditya303
webhook-mailer at python.org
Mon Jun 26 04:51:31 EDT 2023
https://github.com/python/cpython/commit/9e6f8d46150c1a0af09d68ce63c603cf321994aa
commit: 9e6f8d46150c1a0af09d68ce63c603cf321994aa
branch: 3.12
author: Kumar Aditya <59607654+kumaraditya303 at users.noreply.github.com>
committer: kumaraditya303 <59607654+kumaraditya303 at users.noreply.github.com>
date: 2023-06-26T08:51:28Z
summary:
[3.12] gh-105987: Fix reference counting issue in `_asyncio._swap_cur… (#106099)
[3.12] gh-105987: Fix reference counting issue in `_asyncio._swap_current_task` (GH-105989).
(cherry picked from commit d2cbb6e918d9ea39f0dd44acb53270f2dac07454)
Co-authored-by: chgnrdv <52372310+chgnrdv at users.noreply.github.com>
files:
A Misc/NEWS.d/next/Library/2023-06-22-15-21-11.gh-issue-105987.T7Kzrb.rst
M Lib/test/test_asyncio/test_eager_task_factory.py
M Modules/_asynciomodule.c
diff --git a/Lib/test/test_asyncio/test_eager_task_factory.py b/Lib/test/test_asyncio/test_eager_task_factory.py
index fe690934292a8..346888735ff70 100644
--- a/Lib/test/test_asyncio/test_eager_task_factory.py
+++ b/Lib/test/test_asyncio/test_eager_task_factory.py
@@ -12,7 +12,7 @@
from asyncio import tasks
from test.test_asyncio import utils as test_utils
from test.test_asyncio.test_tasks import get_innermost_context
-from test import support
+from test.support.script_helper import assert_python_ok
MOCK_ANY = mock.ANY
@@ -228,6 +228,23 @@ class PyEagerTaskFactoryLoopTests(EagerTaskFactoryLoopTests, test_utils.TestCase
class CEagerTaskFactoryLoopTests(EagerTaskFactoryLoopTests, test_utils.TestCase):
Task = getattr(tasks, '_CTask', None)
+ def test_issue105987(self):
+ code = """if 1:
+ from _asyncio import _swap_current_task
+
+ class DummyTask:
+ pass
+
+ class DummyLoop:
+ pass
+
+ l = DummyLoop()
+ _swap_current_task(l, DummyTask())
+ t = _swap_current_task(l, None)
+ """
+
+ _, out, err = assert_python_ok("-c", code)
+ self.assertFalse(err)
class AsyncTaskCounter:
def __init__(self, loop, *, task_class, eager):
diff --git a/Misc/NEWS.d/next/Library/2023-06-22-15-21-11.gh-issue-105987.T7Kzrb.rst b/Misc/NEWS.d/next/Library/2023-06-22-15-21-11.gh-issue-105987.T7Kzrb.rst
new file mode 100644
index 0000000000000..0bc97da4edf0f
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2023-06-22-15-21-11.gh-issue-105987.T7Kzrb.rst
@@ -0,0 +1 @@
+Fix crash due to improper reference counting in :mod:`asyncio` eager task factory internal routines.
diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c
index 7e33558dba3e3..a465090bfaaa3 100644
--- a/Modules/_asynciomodule.c
+++ b/Modules/_asynciomodule.c
@@ -2047,20 +2047,23 @@ swap_current_task(asyncio_state *state, PyObject *loop, PyObject *task)
}
prev_task = Py_None;
}
+ Py_INCREF(prev_task);
if (task == Py_None) {
if (_PyDict_DelItem_KnownHash(state->current_tasks, loop, hash) == -1) {
- return NULL;
+ goto error;
}
} else {
if (_PyDict_SetItem_KnownHash(state->current_tasks, loop, task, hash) == -1) {
- return NULL;
+ goto error;
}
}
- Py_INCREF(prev_task);
-
return prev_task;
+
+error:
+ Py_DECREF(prev_task);
+ return NULL;
}
/* ----- Task */
More information about the Python-checkins
mailing list