Kaydet (Commit) f0ff849a authored tarafından Victor Stinner's avatar Victor Stinner Kaydeden (comit) GitHub

bpo-30524: Fix _PyStack_UnpackDict() (#1886)

* bpo-29259: Remove unused func parameter of _PyStack_UnpackDict()
* bpo-29286: Change _PyStack_UnpackDict() prototype to be able to
  notify of failure when args is NULL. _PyStack_UnpackDict() now
  returns -1 on error.
üst 570b1c97
......@@ -290,21 +290,23 @@ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
PyObject **values,
PyObject *kwnames);
/* Convert (args, nargs, kwargs) into a (stack, nargs, kwnames).
/* Convert (args, nargs, kwargs: dict) into (stack, nargs, kwnames: tuple).
Return a new stack which should be released by PyMem_Free(), or return
args unchanged if kwargs is NULL or an empty dictionary.
Return 0 on success, raise an exception and return -1 on error.
Write the new stack into *p_stack. If *p_stack is differen than args, it
must be released by PyMem_Free().
The stack uses borrowed references.
The type of keyword keys is not checked, these checks should be done
later (ex: _PyArg_ParseStack). */
PyAPI_FUNC(PyObject **) _PyStack_UnpackDict(
later (ex: _PyArg_ParseStackAndKeywords). */
PyAPI_FUNC(int) _PyStack_UnpackDict(
PyObject **args,
Py_ssize_t nargs,
PyObject *kwargs,
PyObject **kwnames,
PyObject *func);
PyObject ***p_stack,
PyObject **p_kwnames);
/* Call the callable object func with the "fast call" calling convention:
args is a C array for positional arguments (nargs is the number of
......
......@@ -2389,9 +2389,9 @@ _PyStack_AsDict(PyObject **values, PyObject *kwnames)
return kwdict;
}
PyObject **
int
_PyStack_UnpackDict(PyObject **args, Py_ssize_t nargs, PyObject *kwargs,
PyObject **p_kwnames, PyObject *func)
PyObject ***p_stack, PyObject **p_kwnames)
{
PyObject **stack, **kwstack;
Py_ssize_t nkwargs;
......@@ -2402,27 +2402,27 @@ _PyStack_UnpackDict(PyObject **args, Py_ssize_t nargs, PyObject *kwargs,
assert(nargs >= 0);
assert(kwargs == NULL || PyDict_CheckExact(kwargs));
nkwargs = (kwargs != NULL) ? PyDict_Size(kwargs) : 0;
if (!nkwargs) {
if (kwargs == NULL || (nkwargs = PyDict_Size(kwargs)) == 0) {
*p_stack = args;
*p_kwnames = NULL;
return args;
return 0;
}
if ((size_t)nargs > PY_SSIZE_T_MAX / sizeof(stack[0]) - (size_t)nkwargs) {
PyErr_NoMemory();
return NULL;
return -1;
}
stack = PyMem_Malloc((nargs + nkwargs) * sizeof(stack[0]));
if (stack == NULL) {
PyErr_NoMemory();
return NULL;
return -1;
}
kwnames = PyTuple_New(nkwargs);
if (kwnames == NULL) {
PyMem_Free(stack);
return NULL;
return -1;
}
/* Copy position arguments (borrowed references) */
......@@ -2441,8 +2441,9 @@ _PyStack_UnpackDict(PyObject **args, Py_ssize_t nargs, PyObject *kwargs,
i++;
}
*p_stack = stack;
*p_kwnames = kwnames;
return stack;
return 0;
}
PyObject *
......
......@@ -243,8 +243,7 @@ _PyCFunction_FastCallDict(PyObject *func_obj, PyObject **args, Py_ssize_t nargs,
PyObject *kwnames;
_PyCFunctionFast fastmeth = (_PyCFunctionFast)meth;
stack = _PyStack_UnpackDict(args, nargs, kwargs, &kwnames, func_obj);
if (stack == NULL) {
if (_PyStack_UnpackDict(args, nargs, kwargs, &stack, &kwnames) < 0) {
return NULL;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment