diff options
author | Jeroen Demeyer <J.Demeyer@UGent.be> | 2019-05-22 11:09:35 (GMT) |
---|---|---|
committer | Petr Viktorin <encukou@gmail.com> | 2019-05-22 11:09:35 (GMT) |
commit | 77aa396bb9415428de09112ddf6b34bb843811eb (patch) | |
tree | 6e30eb4a5671e2cfb086985b4b8412b337af320d /Objects/call.c | |
parent | b892d3ea468101d35e2fb081002fa693bd86eca9 (diff) | |
download | cpython-77aa396bb9415428de09112ddf6b34bb843811eb.zip cpython-77aa396bb9415428de09112ddf6b34bb843811eb.tar.gz cpython-77aa396bb9415428de09112ddf6b34bb843811eb.tar.bz2 |
bpo-36907: fix refcount bug in _PyStack_UnpackDict() (GH-13381)
Diffstat (limited to 'Objects/call.c')
-rw-r--r-- | Objects/call.c | 17 |
1 files changed, 12 insertions, 5 deletions
diff --git a/Objects/call.c b/Objects/call.c index 337ca81..cb9ccd9 100644 --- a/Objects/call.c +++ b/Objects/call.c @@ -544,10 +544,14 @@ _PyMethodDef_RawFastCallDict(PyMethodDef *method, PyObject *self, } result = (*fastmeth) (self, stack, nargs, kwnames); - if (stack != args) { + if (kwnames != NULL) { + Py_ssize_t i, n = nargs + PyTuple_GET_SIZE(kwnames); + for (i = 0; i < n; i++) { + Py_DECREF(stack[i]); + } PyMem_Free((PyObject **)stack); + Py_DECREF(kwnames); } - Py_XDECREF(kwnames); break; } @@ -1334,8 +1338,11 @@ _PyStack_UnpackDict(PyObject *const *args, Py_ssize_t nargs, PyObject *kwargs, return -1; } - /* Copy position arguments (borrowed references) */ - memcpy(stack, args, nargs * sizeof(stack[0])); + /* Copy positional arguments */ + for (i = 0; i < nargs; i++) { + Py_INCREF(args[i]); + stack[i] = args[i]; + } kwstack = stack + nargs; pos = i = 0; @@ -1344,8 +1351,8 @@ _PyStack_UnpackDict(PyObject *const *args, Py_ssize_t nargs, PyObject *kwargs, called in the performance critical hot code. */ while (PyDict_Next(kwargs, &pos, &key, &value)) { Py_INCREF(key); + Py_INCREF(value); PyTuple_SET_ITEM(kwnames, i, key); - /* The stack contains borrowed references */ kwstack[i] = value; i++; } |