diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2016-05-20 19:31:50 (GMT) |
---|---|---|
committer | Serhiy Storchaka <storchaka@gmail.com> | 2016-05-20 19:31:50 (GMT) |
commit | 2a95219bc42ff23724d3230f3bcdb2584cd07914 (patch) | |
tree | 075bca187f96831e77ebae65720eaaa35e682532 /Modules | |
parent | da23056a3ed33d2ae69752f7d113059333176297 (diff) | |
parent | 13e602ea0f08e8c04d635356375d1d2ab5a9b964 (diff) | |
download | cpython-2a95219bc42ff23724d3230f3bcdb2584cd07914.zip cpython-2a95219bc42ff23724d3230f3bcdb2584cd07914.tar.gz cpython-2a95219bc42ff23724d3230f3bcdb2584cd07914.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.c | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index 9378317..3893523 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -873,6 +873,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) { @@ -3861,6 +3955,7 @@ static PyMethodDef TestMethods[] = { {"test_pep3118_obsolete_write_locks", (PyCFunction)test_pep3118_obsolete_write_locks, METH_NOARGS}, #endif {"getbuffer_with_null_view", getbuffer_with_null_view, METH_O}, + {"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}, |