changeset: 102063:e04c054beb53 branch: 2.7 parent: 102060:399d49d4acae user: Serhiy Storchaka date: Thu Jun 16 22:08:11 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 399d49d4acae -r e04c054beb53 Misc/NEWS --- a/Misc/NEWS Wed Jun 15 17:12:38 2016 -0500 +++ b/Misc/NEWS Thu Jun 16 22:08:11 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 399d49d4acae -r e04c054beb53 Modules/_ctypes/_ctypes.c --- a/Modules/_ctypes/_ctypes.c Wed Jun 15 17:12:38 2016 -0500 +++ b/Modules/_ctypes/_ctypes.c Thu Jun 16 22:08:11 2016 +0300 @@ -1308,8 +1308,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; @@ -1324,8 +1326,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; @@ -1341,8 +1345,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; @@ -1843,8 +1849,10 @@ Py_INCREF(name); PyString_Concat(&name, suffix); - if (name == NULL) + if (name == NULL) { + Py_DECREF(swapped_args); return NULL; + } PyTuple_SET_ITEM(swapped_args, 0, name); for (i=1; iffi_type_pointer = *fmt->pffi_type; stgdict->align = fmt->pffi_type->alignment; @@ -2045,20 +2055,25 @@ PyObject *meth; int x; meth = PyDescr_NewClassMethod(result, ml); - if (!meth) + if (!meth) { + Py_DECREF(result); return NULL; + } #else #error PyObject *meth, *func; int x; func = PyCFunction_New(ml, NULL); - if (!func) + if (!func) { + Py_DECREF(result); return NULL; + } meth = PyObject_CallFunctionObjArgs( (PyObject *)&PyClassMethod_Type, func, NULL); Py_DECREF(func); if (!meth) { + Py_DECREF(result); return NULL; } #endif @@ -2241,8 +2256,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 399d49d4acae -r e04c054beb53 Modules/_ctypes/callproc.c --- a/Modules/_ctypes/callproc.c Wed Jun 15 17:12:38 2016 -0500 +++ b/Modules/_ctypes/callproc.c Thu Jun 16 22:08:11 2016 +0300 @@ -162,8 +162,10 @@ return NULL; memset(space, 0, sizeof(int) * 2); errobj = CAPSULE_NEW(space, CTYPES_CAPSULE_ERROROBJ); - if (errobj == NULL) + if (errobj == NULL) { + PyMem_Free(space); return NULL; + } if (-1 == PyDict_SetItem(dict, error_object_name, errobj)) { Py_DECREF(errobj); @@ -1277,7 +1279,7 @@ PyObject *nameobj; PyObject *ignored; HMODULE hMod; - if (!PyArg_ParseTuple(args, "O|O:LoadLibrary", &nameobj, &ignored)) + if (!PyArg_ParseTuple(args, "S|O:LoadLibrary", &nameobj, &ignored)) return NULL; #ifdef _UNICODE name = alloca((PyString_Size(nameobj) + 1) * sizeof(WCHAR)); @@ -1815,6 +1817,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 399d49d4acae -r e04c054beb53 Modules/_ctypes/cfield.c --- a/Modules/_ctypes/cfield.c Wed Jun 15 17:12:38 2016 -0500 +++ b/Modules/_ctypes/cfield.c Thu Jun 16 22:08:11 2016 +0300 @@ -1313,7 +1313,7 @@ return NULL; size = strlen(data); if (size < length) { - /* This will copy the leading NUL character + /* This will copy the trailing NUL character * if there is space for it. */ ++size; @@ -1508,6 +1508,7 @@ if (value) { Py_ssize_t size = PyUnicode_GET_SIZE(value); if ((unsigned) size != size) { + Py_DECREF(value); PyErr_SetString(PyExc_ValueError, "String too long for BSTR"); return NULL; }