Skip to content

Dangerous usage of "O" format string in _asynciomodule.c #73106

Closed

Description

@vstinner
BPO 28920
Nosy @gvanrossum, @vstinner, @1st1
Files
  • _asyncio.patch
  • 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 = None
    closed_at = <Date 2016-12-15.08:10:13.455>
    created_at = <Date 2016-12-09.13:38:13.443>
    labels = ['3.7', 'expert-asyncio']
    title = 'Dangerous usage of "O" format string in _asynciomodule.c'
    updated_at = <Date 2016-12-15.08:10:13.454>
    user = 'https://github.com/vstinner'

    bugs.python.org fields:

    activity = <Date 2016-12-15.08:10:13.454>
    actor = 'vstinner'
    assignee = 'none'
    closed = True
    closed_date = <Date 2016-12-15.08:10:13.455>
    closer = 'vstinner'
    components = ['asyncio']
    creation = <Date 2016-12-09.13:38:13.443>
    creator = 'vstinner'
    dependencies = []
    files = ['45815']
    hgrepos = []
    issue_num = 28920
    keywords = ['patch']
    message_count = 5.0
    messages = ['282778', '282779', '282781', '282783', '283250']
    nosy_count = 4.0
    nosy_names = ['gvanrossum', 'vstinner', 'python-dev', 'yselivanov']
    pr_nums = []
    priority = 'normal'
    resolution = 'fixed'
    stage = None
    status = 'closed'
    superseder = None
    type = None
    url = 'https://bugs.python.org/issue28920'
    versions = ['Python 3.6', 'Python 3.7']

    Activity

    1. vstinner commented on Dec 9, 2016

      @vstinner
      MemberAuthor

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

    2. vstinner commented on Dec 9, 2016

      @vstinner
      MemberAuthor

      Previous similar bug in generators: issue bpo-21209.

    3. vstinner commented on Dec 9, 2016

      @vstinner
      MemberAuthor

      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.

    4. vstinner commented on Dec 9, 2016

      @vstinner
      MemberAuthor

      Minimum patch for Python 3.6: only modify calls using the "O" format.

    5. python-dev commented on Dec 15, 2016

      python-devmannequin
      Mannequin

      New changeset f2745b64d8b7 by Victor Stinner in branch '3.6':
      _asyncio uses _PyObject_CallMethodIdObjArgs()
      https://hg.python.org/cpython/rev/f2745b64d8b7

    6. transferred this issue fromon Apr 10, 2022
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

    Metadata

    Metadata

    Assignees

    No one assigned

      Projects

      No projects

        Milestone

        No milestone

        Relationships

        None yet

        Development

        No branches or pull requests

        Issue actions