From: Serhiy Storchaka Date: Thu, 16 Jun 2016 19:08:11 +0000 (+0300) Subject: Issue #27330: Fixed possible leaks in the ctypes module. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ef012cc7f7ff8519aba77d8869af70c1a86a98c0;p=python Issue #27330: Fixed possible leaks in the ctypes module. --- diff --git a/Misc/NEWS b/Misc/NEWS index cdf606b8e2..7c755527ba 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -13,6 +13,8 @@ Core and Builtins 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 --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index 86208e2e16..da2aa7d376 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -1308,8 +1308,10 @@ add_methods(PyTypeObject *type, PyMethodDef *meth) 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 @@ add_members(PyTypeObject *type, PyMemberDef *memb) 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 @@ add_getset(PyTypeObject *type, PyGetSetDef *gsp) 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 @@ static PyObject *CreateSwappedType(PyTypeObject *type, PyObject *args, PyObject 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 @@ PyCSimpleType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) 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 @@ converters_from_argtypes(PyObject *ob) 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 --git a/Modules/_ctypes/callproc.c b/Modules/_ctypes/callproc.c index 280a315828..7af4bfb8e7 100644 --- a/Modules/_ctypes/callproc.c +++ b/Modules/_ctypes/callproc.c @@ -162,8 +162,10 @@ _ctypes_get_errobj(int **pspace) 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 @@ static PyObject *load_library(PyObject *self, PyObject *args) 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 @@ POINTER(PyObject *self, PyObject *cls) 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 --git a/Modules/_ctypes/cfield.c b/Modules/_ctypes/cfield.c index 0585ed28dd..75f65a1050 100644 --- a/Modules/_ctypes/cfield.c +++ b/Modules/_ctypes/cfield.c @@ -1313,7 +1313,7 @@ s_set(void *ptr, PyObject *value, Py_ssize_t length) 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 @@ BSTR_set(void *ptr, PyObject *value, Py_ssize_t size) 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; }