From f08173bb939f3d45594cb674acb092af9cf23747 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Thu, 3 Dec 2009 10:59:46 +0000 Subject: [PATCH] Issue #7414: Add missing 'case 'C'' to skipitem() in getargs.c. This was causing PyArg_ParseTupleAndKeywords(args, kwargs, "|CC", ...) to fail with a RuntimeError. Thanks Case Van Horsen for tracking down the source of this error. --- Misc/NEWS | 3 +++ Modules/_testcapimodule.c | 47 +++++++++++++++++++++++++++++++++++++++ Python/getargs.c | 1 + 3 files changed, 51 insertions(+) diff --git a/Misc/NEWS b/Misc/NEWS index 93c4653167..6a216ed4a0 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -121,6 +121,9 @@ Core and Builtins C-API ----- +- Issue #7414: 'C' code wasn't being skipped properly (for keyword arguments) + in PyArg_ParseTupleAndKeywords. + - Issue #Add '%lld' and '%llu' support to PyString_FromFormat(V) and PyErr_Format, on machines with HAVE_LONG_LONG defined. diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index 0ed2111508..f41d4fec03 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -616,6 +616,52 @@ test_s_code(PyObject *self) Py_RETURN_NONE; } +static PyObject * +test_bug_7414(PyObject *self) +{ + /* Issue #7414: for PyArg_ParseTupleAndKeywords, 'C' code wasn't being + skipped properly in skipitem() */ + int a = 0, b = 0, result; + char *kwlist[] = {"a", "b", NULL}; + PyObject *tuple = NULL, *dict = NULL, *b_str; + + tuple = PyTuple_New(0); + if (tuple == NULL) + goto failure; + dict = PyDict_New(); + if (dict == NULL) + goto failure; + b_str = PyUnicode_FromString("b"); + if (b_str == NULL) + goto failure; + result = PyDict_SetItemString(dict, "b", b_str); + Py_DECREF(b_str); + if (result < 0) + goto failure; + + result = PyArg_ParseTupleAndKeywords(tuple, dict, "|CC", + kwlist, &a, &b); + if (!result) + goto failure; + + if (a != 0) + return raiseTestError("test_bug_7414", + "C format code not skipped properly"); + if (b != 'b') + return raiseTestError("test_bug_7414", + "C format code returned wrong value"); + + Py_DECREF(dict); + Py_DECREF(tuple); + Py_RETURN_NONE; + + failure: + Py_XDECREF(dict); + Py_XDECREF(tuple); + return NULL; +} + + static volatile int x; /* Test the u and u# codes for PyArg_ParseTuple. May leak memory in case @@ -1477,6 +1523,7 @@ static PyMethodDef TestMethods[] = { {"test_long_numbits", (PyCFunction)test_long_numbits, METH_NOARGS}, {"test_k_code", (PyCFunction)test_k_code, METH_NOARGS}, {"test_empty_argparse", (PyCFunction)test_empty_argparse,METH_NOARGS}, + {"test_bug_7414", (PyCFunction)test_bug_7414, METH_NOARGS}, {"test_null_strings", (PyCFunction)test_null_strings, METH_NOARGS}, {"test_string_from_format", (PyCFunction)test_string_from_format, METH_NOARGS}, {"test_with_docstring", (PyCFunction)test_with_docstring, METH_NOARGS, diff --git a/Python/getargs.c b/Python/getargs.c index f41cd05eaf..b69aaed56c 100644 --- a/Python/getargs.c +++ b/Python/getargs.c @@ -1772,6 +1772,7 @@ skipitem(const char **p_format, va_list *p_va, int flags) case 'd': /* double */ case 'D': /* complex double */ case 'c': /* char */ + case 'C': /* unicode char */ { (void) va_arg(*p_va, void *); break; -- 2.40.0