]> granicus.if.org Git - python/commitdiff
bpo-30524: Fix _PyStack_UnpackDict() (#1886)
authorVictor Stinner <victor.stinner@gmail.com>
Fri, 9 Jun 2017 11:24:53 +0000 (13:24 +0200)
committerGitHub <noreply@github.com>
Fri, 9 Jun 2017 11:24:53 +0000 (13:24 +0200)
* 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.

Include/abstract.h
Objects/abstract.c
Objects/methodobject.c

index 7d137a22bfb7a8cab97f3a514b00f6fa7f899801..6bb76ec95f1b2e47273c3fd50e3aa89d5c9dc037 100644 (file)
@@ -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
index d838856d452872e714c5472c6b95303c43c1862a..3585b34ca4d8bdf38c5f146d805331f993429748 100644 (file)
@@ -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 *
index c2001f0169b030f316169d7001439426d5506c77..fe52545667f2edf81b5338a84a1cfc2041a77a27 100644 (file)
@@ -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;
         }