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*/ ...@@ -290,21 +290,23 @@ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
PyObject **values, PyObject **values,
PyObject *kwnames); 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 Return 0 on success, raise an exception and return -1 on error.
args unchanged if kwargs is NULL or an empty dictionary.
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 stack uses borrowed references.
The type of keyword keys is not checked, these checks should be done The type of keyword keys is not checked, these checks should be done
later (ex: _PyArg_ParseStack). */ later (ex: _PyArg_ParseStackAndKeywords). */
PyAPI_FUNC(PyObject **) _PyStack_UnpackDict( PyAPI_FUNC(int) _PyStack_UnpackDict(
PyObject **args, PyObject **args,
Py_ssize_t nargs, Py_ssize_t nargs,
PyObject *kwargs, PyObject *kwargs,
PyObject **kwnames, PyObject ***p_stack,
PyObject *func); PyObject **p_kwnames);
/* Call the callable object func with the "fast call" calling convention: /* Call the callable object func with the "fast call" calling convention:
args is a C array for positional arguments (nargs is the number of args is a C array for positional arguments (nargs is the number of
......
...@@ -2389,9 +2389,9 @@ _PyStack_AsDict(PyObject **values, PyObject *kwnames) ...@@ -2389,9 +2389,9 @@ _PyStack_AsDict(PyObject **values, PyObject *kwnames)
return kwdict; return kwdict;
} }
PyObject ** int
_PyStack_UnpackDict(PyObject **args, Py_ssize_t nargs, PyObject *kwargs, _PyStack_UnpackDict(PyObject **args, Py_ssize_t nargs, PyObject *kwargs,
PyObject **p_kwnames, PyObject *func) PyObject ***p_stack, PyObject **p_kwnames)
{ {
PyObject **stack, **kwstack; PyObject **stack, **kwstack;
Py_ssize_t nkwargs; Py_ssize_t nkwargs;
...@@ -2402,27 +2402,27 @@ _PyStack_UnpackDict(PyObject **args, Py_ssize_t nargs, PyObject *kwargs, ...@@ -2402,27 +2402,27 @@ _PyStack_UnpackDict(PyObject **args, Py_ssize_t nargs, PyObject *kwargs,
assert(nargs >= 0); assert(nargs >= 0);
assert(kwargs == NULL || PyDict_CheckExact(kwargs)); assert(kwargs == NULL || PyDict_CheckExact(kwargs));
nkwargs = (kwargs != NULL) ? PyDict_Size(kwargs) : 0; if (kwargs == NULL || (nkwargs = PyDict_Size(kwargs)) == 0) {
if (!nkwargs) { *p_stack = args;
*p_kwnames = NULL; *p_kwnames = NULL;
return args; return 0;
} }
if ((size_t)nargs > PY_SSIZE_T_MAX / sizeof(stack[0]) - (size_t)nkwargs) { if ((size_t)nargs > PY_SSIZE_T_MAX / sizeof(stack[0]) - (size_t)nkwargs) {
PyErr_NoMemory(); PyErr_NoMemory();
return NULL; return -1;
} }
stack = PyMem_Malloc((nargs + nkwargs) * sizeof(stack[0])); stack = PyMem_Malloc((nargs + nkwargs) * sizeof(stack[0]));
if (stack == NULL) { if (stack == NULL) {
PyErr_NoMemory(); PyErr_NoMemory();
return NULL; return -1;
} }
kwnames = PyTuple_New(nkwargs); kwnames = PyTuple_New(nkwargs);
if (kwnames == NULL) { if (kwnames == NULL) {
PyMem_Free(stack); PyMem_Free(stack);
return NULL; return -1;
} }
/* Copy position arguments (borrowed references) */ /* Copy position arguments (borrowed references) */
...@@ -2441,8 +2441,9 @@ _PyStack_UnpackDict(PyObject **args, Py_ssize_t nargs, PyObject *kwargs, ...@@ -2441,8 +2441,9 @@ _PyStack_UnpackDict(PyObject **args, Py_ssize_t nargs, PyObject *kwargs,
i++; i++;
} }
*p_stack = stack;
*p_kwnames = kwnames; *p_kwnames = kwnames;
return stack; return 0;
} }
PyObject * PyObject *
......
...@@ -243,8 +243,7 @@ _PyCFunction_FastCallDict(PyObject *func_obj, PyObject **args, Py_ssize_t nargs, ...@@ -243,8 +243,7 @@ _PyCFunction_FastCallDict(PyObject *func_obj, PyObject **args, Py_ssize_t nargs,
PyObject *kwnames; PyObject *kwnames;
_PyCFunctionFast fastmeth = (_PyCFunctionFast)meth; _PyCFunctionFast fastmeth = (_PyCFunctionFast)meth;
stack = _PyStack_UnpackDict(args, nargs, kwargs, &kwnames, func_obj); if (_PyStack_UnpackDict(args, nargs, kwargs, &stack, &kwnames) < 0) {
if (stack == NULL) {
return NULL; 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