You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Dangerous usage of "O" format string in _asynciomodule.c #73106
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
assignee=Noneclosed_at=<Date2016-12-15.08:10:13.455>created_at=<Date2016-12-09.13:38:13.443>labels= ['3.7', 'expert-asyncio']
title='Dangerous usage of "O" format string in _asynciomodule.c'updated_at=<Date2016-12-15.08:10:13.454>user='https://github.com/vstinner'
The new _asyncio module of Python 3.6 uses the _PyObject_CallMethodId() function to call functions. This function has a weird behaviour when using the format string "O": if the object is a tuple, the tuple is unpacked.
_PyObject_CallMethodId(obj, &PyId_meth, "O", tuple, NULL) calls obj.meth(*tuple) instead of obj.meth(tuple).
I only found one function which may have the bug: task_call_step(). But it seems like this function cannot be called with a tuple as "arg", only with an exception object.
But just in case, I would suggest to replace:
_PyObject_CallMethodId(obj, nameid, "O", arg);
with
_PyObject_CallMethodIdObjArgs(obj, nameid, arg, NULL);
Note: _PyObject_CallMethodId() is called with a NULL terminal in the argument list, but the NULL is useless. A terminator is only required by _PyObject_CallMethodIdObjArgs(). Yeah, Python has a wide choice of functions to call a callable object, with funny APIs... And I'm adding new ones to Python 3.7 ;-)
The issue was in fixed in Python 3.7 with a change made for optimization, not directly to fix this issue:
changeset: 105547:b29c719d5992
tag: tip
user: Victor Stinner <[email protected]>
date: Fri Dec 09 14:24:02 2016 +0100
files: Modules/_asynciomodule.c
description:
Use _PyObject_CallMethodIdObjArgs() in _asyncio
Issue bpo-28915: Replace _PyObject_CallMethodId() with
_PyObject_CallMethodIdObjArgs() when the format string was only made of "O"
formats, PyObject* arguments.
_PyObject_CallMethodIdObjArgs() avoids the creation of a temporary tuple and
doesn't have to parse a format string.
Activity
vstinner commentedon Dec 9, 2016
The new _asyncio module of Python 3.6 uses the _PyObject_CallMethodId() function to call functions. This function has a weird behaviour when using the format string "O": if the object is a tuple, the tuple is unpacked.
_PyObject_CallMethodId(obj, &PyId_meth, "O", tuple, NULL) calls obj.meth(*tuple) instead of obj.meth(tuple).
I only found one function which may have the bug: task_call_step(). But it seems like this function cannot be called with a tuple as "arg", only with an exception object.
But just in case, I would suggest to replace:
_PyObject_CallMethodId(obj, nameid, "O", arg);
with
_PyObject_CallMethodIdObjArgs(obj, nameid, arg, NULL);
Note: _PyObject_CallMethodId() is called with a NULL terminal in the argument list, but the NULL is useless. A terminator is only required by _PyObject_CallMethodIdObjArgs(). Yeah, Python has a wide choice of functions to call a callable object, with funny APIs... And I'm adding new ones to Python 3.7 ;-)
vstinner commentedon Dec 9, 2016
Previous similar bug in generators: issue bpo-21209.
vstinner commentedon Dec 9, 2016
The issue was in fixed in Python 3.7 with a change made for optimization, not directly to fix this issue:
changeset: 105547:b29c719d5992
tag: tip
user: Victor Stinner <[email protected]>
date: Fri Dec 09 14:24:02 2016 +0100
files: Modules/_asynciomodule.c
description:
Use _PyObject_CallMethodIdObjArgs() in _asyncio
Issue bpo-28915: Replace _PyObject_CallMethodId() with
_PyObject_CallMethodIdObjArgs() when the format string was only made of "O"
formats, PyObject* arguments.
_PyObject_CallMethodIdObjArgs() avoids the creation of a temporary tuple and
doesn't have to parse a format string.
vstinner commentedon Dec 9, 2016
Minimum patch for Python 3.6: only modify calls using the "O" format.
python-dev commentedon Dec 15, 2016
New changeset f2745b64d8b7 by Victor Stinner in branch '3.6':
_asyncio uses _PyObject_CallMethodIdObjArgs()
https://hg.python.org/cpython/rev/f2745b64d8b7