[Python-checkins] cpython (merge 3.5 -> default): Issue #27330: Fixed possible leaks in the ctypes module.

serhiy.storchaka python-checkins at python.org
Thu Jun 16 15:10:38 EDT 2016


https://hg.python.org/cpython/rev/27e7945c4ecd
changeset: 102065:27e7945c4ecd
parent: 102062:3d726dbfca31
parent: 102064:41f99ee19804
user: Serhiy Storchaka <storchaka at gmail.com>
date: Thu Jun 16 22:10:13 2016 +0300
summary:
 Issue #27330: Fixed possible leaks in the ctypes module.
files:
 Misc/NEWS | 2 ++
 Modules/_ctypes/_ctypes.c | 25 +++++++++++++++++++------
 Modules/_ctypes/callproc.c | 8 +++++++-
 Modules/_ctypes/cfield.c | 20 +++++---------------
 4 files changed, 33 insertions(+), 22 deletions(-)
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -10,6 +10,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 --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c
--- a/Modules/_ctypes/_ctypes.c
+++ b/Modules/_ctypes/_ctypes.c
@@ -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 --git a/Modules/_ctypes/callproc.c b/Modules/_ctypes/callproc.c
--- a/Modules/_ctypes/callproc.c
+++ b/Modules/_ctypes/callproc.c
@@ -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 --git a/Modules/_ctypes/cfield.c b/Modules/_ctypes/cfield.c
--- a/Modules/_ctypes/cfield.c
+++ b/Modules/_ctypes/cfield.c
@@ -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;
 
-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list

AltStyle によって変換されたページ (->オリジナル) /