]> granicus.if.org Git - python/commitdiff
Merged revisions 53556 via svnmerge from
authorThomas Heller <theller@ctypes.org>
Thu, 25 Jan 2007 19:19:35 +0000 (19:19 +0000)
committerThomas Heller <theller@ctypes.org>
Thu, 25 Jan 2007 19:19:35 +0000 (19:19 +0000)
svn+ssh://pythondev@svn.python.org/python/trunk/Modules/_ctypes

........
  r53556 | thomas.heller | 2007-01-25 19:34:14 +0100 (Do, 25 Jan 2007) | 3 lines

  Fix for #1643874: When calling SysAllocString, create a PyCObject
  which will eventually call SysFreeString to free the BSTR resource.
........

Misc/NEWS
Modules/_ctypes/cfield.c

index 8cff95199e0af84e29fa32b9f3164df6a5c5e9f6..21742f3797ccf1a51d0afe5fa23abc10a560734e 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -154,6 +154,8 @@ Extension Modules
 Library
 -------
 
+- Patch #1643874: memory leak in ctypes fixed.
+
 - Bug #1598181: Avoid O(N**2) bottleneck in subprocess communicate(). 
 
 - Patch #1627441: close sockets properly in urllib2.
index c16a387464f9c928a0dc89daf526a6e2fbbddca0..31c3b99fdda9317a1d77acb55331e54a258e78c3 100644 (file)
@@ -1424,10 +1424,19 @@ Z_get(void *ptr, unsigned size)
 #endif
 
 #ifdef MS_WIN32
+/* We cannot use SysFreeString as the PyCObject_FromVoidPtr
+   because of different calling convention
+*/
+static void _my_SysFreeString(void *p)
+{
+       SysFreeString((BSTR)p);
+}
+
 static PyObject *
 BSTR_set(void *ptr, PyObject *value, unsigned size)
 {
        BSTR bstr;
+       PyObject *result;
 
        /* convert value into a PyUnicodeObject or NULL */
        if (Py_None == value) {
@@ -1455,15 +1464,19 @@ BSTR_set(void *ptr, PyObject *value, unsigned size)
        } else
                bstr = NULL;
 
-       /* free the previous contents, if any */
-       if (*(BSTR *)ptr)
-               SysFreeString(*(BSTR *)ptr);
-       
-       /* and store it */
-       *(BSTR *)ptr = bstr;
+       if (bstr) {
+               result = PyCObject_FromVoidPtr((void *)bstr, _my_SysFreeString);
+               if (result == NULL) {
+                       SysFreeString(bstr);
+                       return NULL;
+               }
+       } else {
+               result = Py_None;
+               Py_INCREF(result);
+       }
 
-       /* We don't need to keep any other object */
-       _RET(value);
+       *(BSTR *)ptr = bstr;
+       return result;
 }