]> granicus.if.org Git - python/commitdiff
Issue #27330: Fixed possible leaks in the ctypes module.
authorSerhiy Storchaka <storchaka@gmail.com>
Thu, 16 Jun 2016 19:08:11 +0000 (22:08 +0300)
committerSerhiy Storchaka <storchaka@gmail.com>
Thu, 16 Jun 2016 19:08:11 +0000 (22:08 +0300)
Misc/NEWS
Modules/_ctypes/_ctypes.c
Modules/_ctypes/callproc.c
Modules/_ctypes/cfield.c

index cdf606b8e201db42921ec55213780b56683096ec..7c755527bae8fa20f3dff3f57ef0d7fe65c584dc 100644 (file)
--- 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.
 
index 86208e2e16d9a8c3bf6459d40f9855d2f9f223f2..da2aa7d376a07c0ad0d87fdcd97d2286701c674b 100644 (file)
@@ -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; i<PyTuple_GET_SIZE(args); ++i) {
@@ -1862,8 +1870,10 @@ static PyObject *CreateSwappedType(PyTypeObject *type, PyObject *args, PyObject
 
     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;
@@ -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!
index 280a31582812002813293c18bd7f0b9e55362cec..7af4bfb8e7da304a466ea7b9916debaeff9fbc5e 100644 (file)
@@ -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);
index 0585ed28dd9ba53ce783718edcff783036a3a01f..75f65a1050d81b658fb352fcc06069dbdcc8e0f8 100644 (file)
@@ -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;
         }