changeset: 102064:41f99ee19804 branch: 3.5 parent: 102061:155e665428c6 user: Serhiy Storchaka date: Thu Jun 16 22:08:46 2016 +0300 files: Misc/NEWS Modules/_ctypes/_ctypes.c Modules/_ctypes/callproc.c Modules/_ctypes/cfield.c description: Issue #27330: Fixed possible leaks in the ctypes module. diff -r 155e665428c6 -r 41f99ee19804 Misc/NEWS --- a/Misc/NEWS Wed Jun 15 17:13:28 2016 -0500 +++ b/Misc/NEWS Thu Jun 16 22:08:46 2016 +0300 @@ -13,6 +13,8 @@ Library ------- +- Issue #27330: Fixed possible leaks in the ctypes module. + - Issue #27238: Got rid of bare excepts in the turtle module. Original patch by Jelle Zijlstra. diff -r 155e665428c6 -r 41f99ee19804 Modules/_ctypes/_ctypes.c --- a/Modules/_ctypes/_ctypes.c Wed Jun 15 17:13:28 2016 -0500 +++ b/Modules/_ctypes/_ctypes.c Thu Jun 16 22:08:46 2016 +0300 @@ -1252,8 +1252,10 @@ descr = PyDescr_NewMethod(type, meth); if (descr == NULL) return -1; - if (PyDict_SetItemString(dict,meth->ml_name, descr) < 0) + if (PyDict_SetItemString(dict, meth->ml_name, descr) < 0) { + Py_DECREF(descr); return -1; + } Py_DECREF(descr); } return 0; @@ -1268,8 +1270,10 @@ descr = PyDescr_NewMember(type, memb); if (descr == NULL) return -1; - if (PyDict_SetItemString(dict, memb->name, descr) < 0) + if (PyDict_SetItemString(dict, memb->name, descr) < 0) { + Py_DECREF(descr); return -1; + } Py_DECREF(descr); } return 0; @@ -1285,8 +1289,10 @@ descr = PyDescr_NewGetSet(type, gsp); if (descr == NULL) return -1; - if (PyDict_SetItemString(dict, gsp->name, descr) < 0) + if (PyDict_SetItemString(dict, gsp->name, descr) < 0) { + Py_DECREF(descr); return -1; + } Py_DECREF(descr); } return 0; @@ -1778,6 +1784,7 @@ newname = PyUnicode_Concat(name, suffix); if (newname == NULL) { + Py_DECREF(swapped_args); return NULL; } @@ -1797,8 +1804,10 @@ stgdict = (StgDictObject *)PyObject_CallObject( (PyObject *)&PyCStgDict_Type, NULL); - if (!stgdict) /* XXX leaks result! */ + if (!stgdict) { + Py_DECREF(result); return NULL; + } stgdict->ffi_type_pointer = *fmt->pffi_type; stgdict->align = fmt->pffi_type->alignment; @@ -1978,8 +1987,10 @@ PyObject *meth; int x; meth = PyDescr_NewClassMethod(result, ml); - if (!meth) + if (!meth) { + Py_DECREF(result); return NULL; + } x = PyDict_SetItemString(result->tp_dict, ml->ml_name, meth); @@ -2159,8 +2170,10 @@ nArgs = PyTuple_GET_SIZE(ob); converters = PyTuple_New(nArgs); - if (!converters) + if (!converters) { + Py_DECREF(ob); return NULL; + } /* I have to check if this is correct. Using c_char, which has a size of 1, will be assumed to be pushed as only one byte! diff -r 155e665428c6 -r 41f99ee19804 Modules/_ctypes/callproc.c --- a/Modules/_ctypes/callproc.c Wed Jun 15 17:13:28 2016 -0500 +++ b/Modules/_ctypes/callproc.c Thu Jun 16 22:08:46 2016 +0300 @@ -157,8 +157,10 @@ return NULL; memset(space, 0, sizeof(int) * 2); errobj = PyCapsule_New(space, CTYPES_CAPSULE_NAME_PYMEM, pymem_destructor); - if (errobj == NULL) + if (errobj == NULL) { + PyMem_Free(space); return NULL; + } if (-1 == PyDict_SetItem(dict, error_object_name, errobj)) { Py_DECREF(errobj); @@ -1681,6 +1683,10 @@ if (result == NULL) return result; key = PyLong_FromVoidPtr(result); + if (key == NULL) { + Py_DECREF(result); + return NULL; + } } else if (PyType_Check(cls)) { typ = (PyTypeObject *)cls; buf = PyMem_Malloc(strlen(typ->tp_name) + 3 + 1); diff -r 155e665428c6 -r 41f99ee19804 Modules/_ctypes/cfield.c --- a/Modules/_ctypes/cfield.c Wed Jun 15 17:13:28 2016 -0500 +++ b/Modules/_ctypes/cfield.c Thu Jun 16 22:08:46 2016 +0300 @@ -1246,8 +1246,7 @@ "unicode string expected instead of %s instance", value->ob_type->tp_name); return NULL; - } else - Py_INCREF(value); + } wstr = PyUnicode_AsUnicodeAndSize(value, &size); if (wstr == NULL) @@ -1256,7 +1255,6 @@ PyErr_Format(PyExc_ValueError, "string too long (%zd, maximum length %zd)", size, length); - Py_DECREF(value); return NULL; } else if (size < length-1) /* copy terminating NUL character if there is space */ @@ -1266,6 +1264,7 @@ return NULL; } + Py_INCREF(value); return value; } @@ -1292,9 +1291,7 @@ char *data; Py_ssize_t size; - if(PyBytes_Check(value)) { - Py_INCREF(value); - } else { + if(!PyBytes_Check(value)) { PyErr_Format(PyExc_TypeError, "expected bytes, %s found", value->ob_type->tp_name); @@ -1302,11 +1299,9 @@ } data = PyBytes_AS_STRING(value); - if (!data) - return NULL; size = strlen(data); /* XXX Why not Py_SIZE(value)? */ if (size < length) { - /* This will copy the leading NUL character + /* This will copy the terminating NUL character * if there is space for it. */ ++size; @@ -1314,13 +1309,11 @@ PyErr_Format(PyExc_ValueError, "bytes too long (%zd, maximum length %zd)", size, length); - Py_DECREF(value); return NULL; } /* Also copy the terminating NUL character if there is space */ memcpy((char *)ptr, data, size); - Py_DECREF(value); _RET(value); } @@ -1428,9 +1421,7 @@ /* convert value into a PyUnicodeObject or NULL */ if (Py_None == value) { value = NULL; - } else if (PyUnicode_Check(value)) { - Py_INCREF(value); /* for the descref below */ - } else { + } else if (!PyUnicode_Check(value)) { PyErr_Format(PyExc_TypeError, "unicode string expected instead of %s instance", value->ob_type->tp_name); @@ -1449,7 +1440,6 @@ return NULL; } bstr = SysAllocStringLen(wvalue, (unsigned)wsize); - Py_DECREF(value); } else bstr = NULL;