summaryrefslogtreecommitdiffstats
path: root/Modules
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2016-05-20 19:31:24 (GMT)
committerSerhiy Storchaka <storchaka@gmail.com>2016-05-20 19:31:24 (GMT)
commit12cf60c7fa8f49997ce4d20be3bd814d736feeca (patch)
tree7cc41ee2ca32706d87aeec07de3883685b158be4 /Modules
parent6546d7cac49c6c1e80115f4b64cbfd5ae8c68302 (diff)
downloadcpython-12cf60c7fa8f49997ce4d20be3bd814d736feeca.zip
cpython-12cf60c7fa8f49997ce4d20be3bd814d736feeca.tar.gz
cpython-12cf60c7fa8f49997ce4d20be3bd814d736feeca.tar.bz2
Issue #26168: Fixed possible refleaks in failing Py_BuildValue() with the "N"
format unit.
Diffstat (limited to 'Modules')
-rw-r--r--Modules/_testcapimodule.c95
1 files changed, 95 insertions, 0 deletions
diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c
index 95a0920..69f59fc 100644
--- a/Modules/_testcapimodule.c
+++ b/Modules/_testcapimodule.c
@@ -931,6 +931,100 @@ test_L_code(PyObject *self)
#endif /* ifdef HAVE_LONG_LONG */
static PyObject *
+return_none(void *unused)
+{
+ Py_RETURN_NONE;
+}
+
+static PyObject *
+raise_error(void *unused)
+{
+ PyErr_SetNone(PyExc_ValueError);
+ return NULL;
+}
+
+static int
+test_buildvalue_N_error(const char *fmt)
+{
+ PyObject *arg, *res;
+
+ arg = PyList_New(0);
+ if (arg == NULL) {
+ return -1;
+ }
+
+ Py_INCREF(arg);
+ res = Py_BuildValue(fmt, return_none, NULL, arg);
+ if (res == NULL) {
+ return -1;
+ }
+ Py_DECREF(res);
+ if (Py_REFCNT(arg) != 1) {
+ PyErr_Format(TestError, "test_buildvalue_N: "
+ "arg was not decrefed in successful "
+ "Py_BuildValue(\"%s\")", fmt);
+ return -1;
+ }
+
+ Py_INCREF(arg);
+ res = Py_BuildValue(fmt, raise_error, NULL, arg);
+ if (res != NULL || !PyErr_Occurred()) {
+ PyErr_Format(TestError, "test_buildvalue_N: "
+ "Py_BuildValue(\"%s\") didn't complain", fmt);
+ return -1;
+ }
+ PyErr_Clear();
+ if (Py_REFCNT(arg) != 1) {
+ PyErr_Format(TestError, "test_buildvalue_N: "
+ "arg was not decrefed in failed "
+ "Py_BuildValue(\"%s\")", fmt);
+ return -1;
+ }
+ Py_DECREF(arg);
+ return 0;
+}
+
+static PyObject *
+test_buildvalue_N(PyObject *self, PyObject *noargs)
+{
+ PyObject *arg, *res;
+
+ arg = PyList_New(0);
+ if (arg == NULL) {
+ return NULL;
+ }
+ Py_INCREF(arg);
+ res = Py_BuildValue("N", arg);
+ if (res == NULL) {
+ return NULL;
+ }
+ if (res != arg) {
+ return raiseTestError("test_buildvalue_N",
+ "Py_BuildValue(\"N\") returned wrong result");
+ }
+ if (Py_REFCNT(arg) != 2) {
+ return raiseTestError("test_buildvalue_N",
+ "arg was not decrefed in Py_BuildValue(\"N\")");
+ }
+ Py_DECREF(res);
+ Py_DECREF(arg);
+
+ if (test_buildvalue_N_error("O&N") < 0)
+ return NULL;
+ if (test_buildvalue_N_error("(O&N)") < 0)
+ return NULL;
+ if (test_buildvalue_N_error("[O&N]") < 0)
+ return NULL;
+ if (test_buildvalue_N_error("{O&N}") < 0)
+ return NULL;
+ if (test_buildvalue_N_error("{()O&(())N}") < 0)
+ return NULL;
+
+ Py_RETURN_NONE;
+}
+
+
+static PyObject *
get_args(PyObject *self, PyObject *args)
{
if (args == NULL) {
@@ -2414,6 +2508,7 @@ static PyMethodDef TestMethods[] = {
{"test_with_docstring", (PyCFunction)test_with_docstring, METH_NOARGS,
PyDoc_STR("This is a pretty normal docstring.")},
+ {"test_buildvalue_N", test_buildvalue_N, METH_NOARGS},
{"get_args", get_args, METH_VARARGS},
{"get_kwargs", (PyCFunction)get_kwargs, METH_VARARGS|METH_KEYWORDS},
{"getargs_tuple", getargs_tuple, METH_VARARGS},