Skip to content

Commit f0ff849

Browse files
authored
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.
1 parent 570b1c9 commit f0ff849

File tree

3 files changed

+20
-18
lines changed

3 files changed

+20
-18
lines changed

Include/abstract.h

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -290,21 +290,23 @@ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
290290
PyObject **values,
291291
PyObject *kwnames);
292292

293-
/* Convert (args, nargs, kwargs) into a (stack, nargs, kwnames).
293+
/* Convert (args, nargs, kwargs: dict) into (stack, nargs, kwnames: tuple).
294294
295-
Return a new stack which should be released by PyMem_Free(), or return
296-
args unchanged if kwargs is NULL or an empty dictionary.
295+
Return 0 on success, raise an exception and return -1 on error.
296+
297+
Write the new stack into *p_stack. If *p_stack is differen than args, it
298+
must be released by PyMem_Free().
297299
298300
The stack uses borrowed references.
299301
300302
The type of keyword keys is not checked, these checks should be done
301-
later (ex: _PyArg_ParseStack). */
302-
PyAPI_FUNC(PyObject **) _PyStack_UnpackDict(
303+
later (ex: _PyArg_ParseStackAndKeywords). */
304+
PyAPI_FUNC(int) _PyStack_UnpackDict(
303305
PyObject **args,
304306
Py_ssize_t nargs,
305307
PyObject *kwargs,
306-
PyObject **kwnames,
307-
PyObject *func);
308+
PyObject ***p_stack,
309+
PyObject **p_kwnames);
308310

309311
/* Call the callable object func with the "fast call" calling convention:
310312
args is a C array for positional arguments (nargs is the number of

Objects/abstract.c

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2389,9 +2389,9 @@ _PyStack_AsDict(PyObject **values, PyObject *kwnames)
23892389
return kwdict;
23902390
}
23912391

2392-
PyObject **
2392+
int
23932393
_PyStack_UnpackDict(PyObject **args, Py_ssize_t nargs, PyObject *kwargs,
2394-
PyObject **p_kwnames, PyObject *func)
2394+
PyObject ***p_stack, PyObject **p_kwnames)
23952395
{
23962396
PyObject **stack, **kwstack;
23972397
Py_ssize_t nkwargs;
@@ -2402,27 +2402,27 @@ _PyStack_UnpackDict(PyObject **args, Py_ssize_t nargs, PyObject *kwargs,
24022402
assert(nargs >= 0);
24032403
assert(kwargs == NULL || PyDict_CheckExact(kwargs));
24042404

2405-
nkwargs = (kwargs != NULL) ? PyDict_Size(kwargs) : 0;
2406-
if (!nkwargs) {
2405+
if (kwargs == NULL || (nkwargs = PyDict_Size(kwargs)) == 0) {
2406+
*p_stack = args;
24072407
*p_kwnames = NULL;
2408-
return args;
2408+
return 0;
24092409
}
24102410

24112411
if ((size_t)nargs > PY_SSIZE_T_MAX / sizeof(stack[0]) - (size_t)nkwargs) {
24122412
PyErr_NoMemory();
2413-
return NULL;
2413+
return -1;
24142414
}
24152415

24162416
stack = PyMem_Malloc((nargs + nkwargs) * sizeof(stack[0]));
24172417
if (stack == NULL) {
24182418
PyErr_NoMemory();
2419-
return NULL;
2419+
return -1;
24202420
}
24212421

24222422
kwnames = PyTuple_New(nkwargs);
24232423
if (kwnames == NULL) {
24242424
PyMem_Free(stack);
2425-
return NULL;
2425+
return -1;
24262426
}
24272427

24282428
/* Copy position arguments (borrowed references) */
@@ -2441,8 +2441,9 @@ _PyStack_UnpackDict(PyObject **args, Py_ssize_t nargs, PyObject *kwargs,
24412441
i++;
24422442
}
24432443

2444+
*p_stack = stack;
24442445
*p_kwnames = kwnames;
2445-
return stack;
2446+
return 0;
24462447
}
24472448

24482449
PyObject *

Objects/methodobject.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -243,8 +243,7 @@ _PyCFunction_FastCallDict(PyObject *func_obj, PyObject **args, Py_ssize_t nargs,
243243
PyObject *kwnames;
244244
_PyCFunctionFast fastmeth = (_PyCFunctionFast)meth;
245245

246-
stack = _PyStack_UnpackDict(args, nargs, kwargs, &kwnames, func_obj);
247-
if (stack == NULL) {
246+
if (_PyStack_UnpackDict(args, nargs, kwargs, &stack, &kwnames) < 0) {
248247
return NULL;
249248
}
250249

0 commit comments

Comments
 (0)