_PyStack_UnpackDict() now returns -1 on error
Issue #29286. Change _PyStack_UnpackDict() prototype to be able to notify of failure when args is NULL.
This commit is contained in:
parent
29d39cc8f5
commit
998c20962c
|
@ -177,20 +177,23 @@ PyAPI_FUNC(PyObject *) _PyStack_AsDict(
|
|||
PyObject **values,
|
||||
PyObject *kwnames);
|
||||
|
||||
/* Convert (args, nargs, kwargs) into a (stack, nargs, kwnames).
|
||||
/* Convert (args, nargs, kwargs: dict) into a (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_ParseStackAndKeywords). */
|
||||
PyAPI_FUNC(PyObject **) _PyStack_UnpackDict(
|
||||
PyAPI_FUNC(int) _PyStack_UnpackDict(
|
||||
PyObject **args,
|
||||
Py_ssize_t nargs,
|
||||
PyObject *kwargs,
|
||||
PyObject **kwnames,
|
||||
PyObject ***p_stack,
|
||||
PyObject **p_kwnames,
|
||||
PyObject *func);
|
||||
|
||||
/* Suggested size (number of positional arguments) for arrays of PyObject*
|
||||
|
|
|
@ -2421,9 +2421,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 *func)
|
||||
{
|
||||
PyObject **stack, **kwstack;
|
||||
Py_ssize_t nkwargs;
|
||||
|
@ -2435,25 +2435,26 @@ _PyStack_UnpackDict(PyObject **args, Py_ssize_t nargs, PyObject *kwargs,
|
|||
assert(kwargs == NULL || PyDict_CheckExact(kwargs));
|
||||
|
||||
if (kwargs == NULL || (nkwargs = PyDict_GET_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) */
|
||||
|
@ -2472,8 +2473,9 @@ _PyStack_UnpackDict(PyObject **args, Py_ssize_t nargs, PyObject *kwargs,
|
|||
i++;
|
||||
}
|
||||
|
||||
*p_stack = stack;
|
||||
*p_kwnames = kwnames;
|
||||
return stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyObject *
|
||||
|
|
|
@ -240,8 +240,8 @@ _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, func_obj) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue