Commit adef6460 authored by Serhiy Storchaka's avatar Serhiy Storchaka

Issue #27330: Fixed possible leaks in the ctypes module.

parent f88d83b9
...@@ -13,6 +13,8 @@ Core and Builtins ...@@ -13,6 +13,8 @@ Core and Builtins
Library Library
------- -------
- Issue #27330: Fixed possible leaks in the ctypes module.
- Issue #27238: Got rid of bare excepts in the turtle module. Original patch - Issue #27238: Got rid of bare excepts in the turtle module. Original patch
by Jelle Zijlstra. by Jelle Zijlstra.
......
...@@ -1252,8 +1252,10 @@ add_methods(PyTypeObject *type, PyMethodDef *meth) ...@@ -1252,8 +1252,10 @@ add_methods(PyTypeObject *type, PyMethodDef *meth)
descr = PyDescr_NewMethod(type, meth); descr = PyDescr_NewMethod(type, meth);
if (descr == NULL) if (descr == NULL)
return -1; 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; return -1;
}
Py_DECREF(descr); Py_DECREF(descr);
} }
return 0; return 0;
...@@ -1268,8 +1270,10 @@ add_members(PyTypeObject *type, PyMemberDef *memb) ...@@ -1268,8 +1270,10 @@ add_members(PyTypeObject *type, PyMemberDef *memb)
descr = PyDescr_NewMember(type, memb); descr = PyDescr_NewMember(type, memb);
if (descr == NULL) if (descr == NULL)
return -1; return -1;
if (PyDict_SetItemString(dict, memb->name, descr) < 0) if (PyDict_SetItemString(dict, memb->name, descr) < 0) {
Py_DECREF(descr);
return -1; return -1;
}
Py_DECREF(descr); Py_DECREF(descr);
} }
return 0; return 0;
...@@ -1285,8 +1289,10 @@ add_getset(PyTypeObject *type, PyGetSetDef *gsp) ...@@ -1285,8 +1289,10 @@ add_getset(PyTypeObject *type, PyGetSetDef *gsp)
descr = PyDescr_NewGetSet(type, gsp); descr = PyDescr_NewGetSet(type, gsp);
if (descr == NULL) if (descr == NULL)
return -1; return -1;
if (PyDict_SetItemString(dict, gsp->name, descr) < 0) if (PyDict_SetItemString(dict, gsp->name, descr) < 0) {
Py_DECREF(descr);
return -1; return -1;
}
Py_DECREF(descr); Py_DECREF(descr);
} }
return 0; return 0;
...@@ -1778,6 +1784,7 @@ static PyObject *CreateSwappedType(PyTypeObject *type, PyObject *args, PyObject ...@@ -1778,6 +1784,7 @@ static PyObject *CreateSwappedType(PyTypeObject *type, PyObject *args, PyObject
newname = PyUnicode_Concat(name, suffix); newname = PyUnicode_Concat(name, suffix);
if (newname == NULL) { if (newname == NULL) {
Py_DECREF(swapped_args);
return NULL; return NULL;
} }
...@@ -1797,8 +1804,10 @@ static PyObject *CreateSwappedType(PyTypeObject *type, PyObject *args, PyObject ...@@ -1797,8 +1804,10 @@ static PyObject *CreateSwappedType(PyTypeObject *type, PyObject *args, PyObject
stgdict = (StgDictObject *)PyObject_CallObject( stgdict = (StgDictObject *)PyObject_CallObject(
(PyObject *)&PyCStgDict_Type, NULL); (PyObject *)&PyCStgDict_Type, NULL);
if (!stgdict) /* XXX leaks result! */ if (!stgdict) {
Py_DECREF(result);
return NULL; return NULL;
}
stgdict->ffi_type_pointer = *fmt->pffi_type; stgdict->ffi_type_pointer = *fmt->pffi_type;
stgdict->align = fmt->pffi_type->alignment; stgdict->align = fmt->pffi_type->alignment;
...@@ -1978,8 +1987,10 @@ PyCSimpleType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) ...@@ -1978,8 +1987,10 @@ PyCSimpleType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
PyObject *meth; PyObject *meth;
int x; int x;
meth = PyDescr_NewClassMethod(result, ml); meth = PyDescr_NewClassMethod(result, ml);
if (!meth) if (!meth) {
Py_DECREF(result);
return NULL; return NULL;
}
x = PyDict_SetItemString(result->tp_dict, x = PyDict_SetItemString(result->tp_dict,
ml->ml_name, ml->ml_name,
meth); meth);
...@@ -2159,8 +2170,10 @@ converters_from_argtypes(PyObject *ob) ...@@ -2159,8 +2170,10 @@ converters_from_argtypes(PyObject *ob)
nArgs = PyTuple_GET_SIZE(ob); nArgs = PyTuple_GET_SIZE(ob);
converters = PyTuple_New(nArgs); converters = PyTuple_New(nArgs);
if (!converters) if (!converters) {
Py_DECREF(ob);
return NULL; return NULL;
}
/* I have to check if this is correct. Using c_char, which has a size /* 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! of 1, will be assumed to be pushed as only one byte!
......
...@@ -157,8 +157,10 @@ _ctypes_get_errobj(int **pspace) ...@@ -157,8 +157,10 @@ _ctypes_get_errobj(int **pspace)
return NULL; return NULL;
memset(space, 0, sizeof(int) * 2); memset(space, 0, sizeof(int) * 2);
errobj = PyCapsule_New(space, CTYPES_CAPSULE_NAME_PYMEM, pymem_destructor); errobj = PyCapsule_New(space, CTYPES_CAPSULE_NAME_PYMEM, pymem_destructor);
if (errobj == NULL) if (errobj == NULL) {
PyMem_Free(space);
return NULL; return NULL;
}
if (-1 == PyDict_SetItem(dict, error_object_name, if (-1 == PyDict_SetItem(dict, error_object_name,
errobj)) { errobj)) {
Py_DECREF(errobj); Py_DECREF(errobj);
...@@ -1681,6 +1683,10 @@ POINTER(PyObject *self, PyObject *cls) ...@@ -1681,6 +1683,10 @@ POINTER(PyObject *self, PyObject *cls)
if (result == NULL) if (result == NULL)
return result; return result;
key = PyLong_FromVoidPtr(result); key = PyLong_FromVoidPtr(result);
if (key == NULL) {
Py_DECREF(result);
return NULL;
}
} else if (PyType_Check(cls)) { } else if (PyType_Check(cls)) {
typ = (PyTypeObject *)cls; typ = (PyTypeObject *)cls;
buf = PyMem_Malloc(strlen(typ->tp_name) + 3 + 1); buf = PyMem_Malloc(strlen(typ->tp_name) + 3 + 1);
......
...@@ -1246,8 +1246,7 @@ U_set(void *ptr, PyObject *value, Py_ssize_t length) ...@@ -1246,8 +1246,7 @@ U_set(void *ptr, PyObject *value, Py_ssize_t length)
"unicode string expected instead of %s instance", "unicode string expected instead of %s instance",
value->ob_type->tp_name); value->ob_type->tp_name);
return NULL; return NULL;
} else }
Py_INCREF(value);
wstr = PyUnicode_AsUnicodeAndSize(value, &size); wstr = PyUnicode_AsUnicodeAndSize(value, &size);
if (wstr == NULL) if (wstr == NULL)
...@@ -1256,7 +1255,6 @@ U_set(void *ptr, PyObject *value, Py_ssize_t length) ...@@ -1256,7 +1255,6 @@ U_set(void *ptr, PyObject *value, Py_ssize_t length)
PyErr_Format(PyExc_ValueError, PyErr_Format(PyExc_ValueError,
"string too long (%zd, maximum length %zd)", "string too long (%zd, maximum length %zd)",
size, length); size, length);
Py_DECREF(value);
return NULL; return NULL;
} else if (size < length-1) } else if (size < length-1)
/* copy terminating NUL character if there is space */ /* copy terminating NUL character if there is space */
...@@ -1266,6 +1264,7 @@ U_set(void *ptr, PyObject *value, Py_ssize_t length) ...@@ -1266,6 +1264,7 @@ U_set(void *ptr, PyObject *value, Py_ssize_t length)
return NULL; return NULL;
} }
Py_INCREF(value);
return value; return value;
} }
...@@ -1292,9 +1291,7 @@ s_set(void *ptr, PyObject *value, Py_ssize_t length) ...@@ -1292,9 +1291,7 @@ s_set(void *ptr, PyObject *value, Py_ssize_t length)
char *data; char *data;
Py_ssize_t size; Py_ssize_t size;
if(PyBytes_Check(value)) { if(!PyBytes_Check(value)) {
Py_INCREF(value);
} else {
PyErr_Format(PyExc_TypeError, PyErr_Format(PyExc_TypeError,
"expected bytes, %s found", "expected bytes, %s found",
value->ob_type->tp_name); value->ob_type->tp_name);
...@@ -1302,11 +1299,9 @@ s_set(void *ptr, PyObject *value, Py_ssize_t length) ...@@ -1302,11 +1299,9 @@ s_set(void *ptr, PyObject *value, Py_ssize_t length)
} }
data = PyBytes_AS_STRING(value); data = PyBytes_AS_STRING(value);
if (!data)
return NULL;
size = strlen(data); /* XXX Why not Py_SIZE(value)? */ size = strlen(data); /* XXX Why not Py_SIZE(value)? */
if (size < length) { if (size < length) {
/* This will copy the leading NUL character /* This will copy the terminating NUL character
* if there is space for it. * if there is space for it.
*/ */
++size; ++size;
...@@ -1314,13 +1309,11 @@ s_set(void *ptr, PyObject *value, Py_ssize_t length) ...@@ -1314,13 +1309,11 @@ s_set(void *ptr, PyObject *value, Py_ssize_t length)
PyErr_Format(PyExc_ValueError, PyErr_Format(PyExc_ValueError,
"bytes too long (%zd, maximum length %zd)", "bytes too long (%zd, maximum length %zd)",
size, length); size, length);
Py_DECREF(value);
return NULL; return NULL;
} }
/* Also copy the terminating NUL character if there is space */ /* Also copy the terminating NUL character if there is space */
memcpy((char *)ptr, data, size); memcpy((char *)ptr, data, size);
Py_DECREF(value);
_RET(value); _RET(value);
} }
...@@ -1428,9 +1421,7 @@ BSTR_set(void *ptr, PyObject *value, Py_ssize_t size) ...@@ -1428,9 +1421,7 @@ BSTR_set(void *ptr, PyObject *value, Py_ssize_t size)
/* convert value into a PyUnicodeObject or NULL */ /* convert value into a PyUnicodeObject or NULL */
if (Py_None == value) { if (Py_None == value) {
value = NULL; value = NULL;
} else if (PyUnicode_Check(value)) { } else if (!PyUnicode_Check(value)) {
Py_INCREF(value); /* for the descref below */
} else {
PyErr_Format(PyExc_TypeError, PyErr_Format(PyExc_TypeError,
"unicode string expected instead of %s instance", "unicode string expected instead of %s instance",
value->ob_type->tp_name); value->ob_type->tp_name);
...@@ -1449,7 +1440,6 @@ BSTR_set(void *ptr, PyObject *value, Py_ssize_t size) ...@@ -1449,7 +1440,6 @@ BSTR_set(void *ptr, PyObject *value, Py_ssize_t size)
return NULL; return NULL;
} }
bstr = SysAllocStringLen(wvalue, (unsigned)wsize); bstr = SysAllocStringLen(wvalue, (unsigned)wsize);
Py_DECREF(value);
} else } else
bstr = NULL; bstr = NULL;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment