summaryrefslogtreecommitdiffstats
path: root/Modules
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2016-05-20 19:31:14 (GMT)
committerSerhiy Storchaka <storchaka@gmail.com>2016-05-20 19:31:14 (GMT)
commit13e602ea0f08e8c04d635356375d1d2ab5a9b964 (patch)
tree1c6c4f354fbed67740dc674f4057537a8e682394 /Modules
parent3dc5129d4fd26d97c1cd8176f6e085db99e38036 (diff)
downloadcpython-13e602ea0f08e8c04d635356375d1d2ab5a9b964.zip
cpython-13e602ea0f08e8c04d635356375d1d2ab5a9b964.tar.gz
cpython-13e602ea0f08e8c04d635356375d1d2ab5a9b964.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 d86af15..3810e94 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) {
@@ -3728,6 +3822,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},