changeset 4607:70600448f9e7 v7.3.1051

updated for version 7.3.1051 Problem: Python: possible memory leaks. Solution: Python patch 12: fix the leaks (ZyX)
author Bram Moolenaar <bram@vim.org>
date Wed, 29 May 2013 22:49:26 +0200
parents 6e6f35424a47
children a1d3d9db4340
files src/if_py_both.h src/version.c
diffstat 2 files changed, 43 insertions(+), 23 deletions(-) [+]
line wrap: on
line diff
--- a/src/if_py_both.h
+++ b/src/if_py_both.h
@@ -32,9 +32,17 @@ typedef int Py_ssize_t;  /* Python 2.4 a
 
 #define DICTKEY_DECL \
     PyObject	*dictkey_todecref;
-#define DICTKEY_GET(err) \
+#define DICTKEY_GET(err, decref) \
     if (!(key = StringToChars(keyObject, &dictkey_todecref))) \
+    { \
+	if (decref) \
+	{ \
+	    Py_DECREF(keyObject); \
+	} \
 	return err; \
+    } \
+    if (decref && !dictkey_todecref) \
+	dictkey_todecref = keyObject; \
     if (*key == NUL) \
     { \
 	PyErr_SetString(PyExc_ValueError, _("empty keys are not allowed")); \
@@ -602,7 +610,6 @@ VimToPython(typval_T *our_tv, int depth,
 		    Py_DECREF(newObj);
 		    return NULL;
 		}
-		Py_DECREF(newObj);
 	    }
 	}
     }
@@ -947,7 +954,7 @@ DictionaryItem(DictionaryObject *self, P
     dictitem_T	*di;
     DICTKEY_DECL
 
-    DICTKEY_GET(NULL)
+    DICTKEY_GET(NULL, 0)
 
     di = dict_find(self->dict, key, -1);
 
@@ -977,7 +984,7 @@ DictionaryAssItem(DictionaryObject *self
 	return -1;
     }
 
-    DICTKEY_GET(-1)
+    DICTKEY_GET(-1, 0)
 
     di = dict_find(dict, key, -1);
 
@@ -1650,7 +1657,7 @@ OptionsItem(OptionsObject *self, PyObjec
     if (self->Check(self->from))
 	return NULL;
 
-    DICTKEY_GET(NULL)
+    DICTKEY_GET(NULL, 0)
 
     flags = get_option_value_strict(key, &numval, &stringval,
 				    self->opt_type, self->from);
@@ -1789,7 +1796,7 @@ OptionsAssItem(OptionsObject *self, PyOb
     if (self->Check(self->from))
 	return -1;
 
-    DICTKEY_GET(-1)
+    DICTKEY_GET(-1, 0)
 
     flags = get_option_value_strict(key, NULL, NULL,
 				    self->opt_type, self->from);
@@ -4029,12 +4036,10 @@ pydict_to_tv(PyObject *obj, typval_T *tv
     {
 	DICTKEY_DECL
 
-	if (keyObject == NULL)
+	if (keyObject == NULL || valObject == NULL)
 	    return -1;
-	if (valObject == NULL)
-	    return -1;
-
-	DICTKEY_GET(-1)
+
+	DICTKEY_GET(-1, 0)
 
 	di = dictitem_alloc(key);
 
@@ -4055,6 +4060,7 @@ pydict_to_tv(PyObject *obj, typval_T *tv
 
 	if (dict_add(dict, di) == FAIL)
 	{
+	    clear_tv(&di->di_tv);
 	    vim_free(di);
 	    PyErr_SetVim(_("failed to add key to dictionary"));
 	    return -1;
@@ -4100,24 +4106,25 @@ pymap_to_tv(PyObject *obj, typval_T *tv,
 	    return -1;
 	}
 
-	keyObject = PyTuple_GetItem(litem, 0);
-	if (keyObject == NULL)
+	if (!(keyObject = PyTuple_GetItem(litem, 0)))
 	{
 	    Py_DECREF(list);
 	    Py_DECREF(litem);
 	    return -1;
 	}
 
-	DICTKEY_GET(-1)
-
-	valObject = PyTuple_GetItem(litem, 1);
-	if (valObject == NULL)
+	DICTKEY_GET(-1, 1)
+
+	if (!(valObject = PyTuple_GetItem(litem, 1)))
 	{
 	    Py_DECREF(list);
 	    Py_DECREF(litem);
+	    DICTKEY_UNREF
 	    return -1;
 	}
 
+	Py_DECREF(litem);
+
 	di = dictitem_alloc(key);
 
 	DICTKEY_UNREF
@@ -4125,7 +4132,7 @@ pymap_to_tv(PyObject *obj, typval_T *tv,
 	if (di == NULL)
 	{
 	    Py_DECREF(list);
-	    Py_DECREF(litem);
+	    Py_DECREF(valObject);
 	    PyErr_NoMemory();
 	    return -1;
 	}
@@ -4135,18 +4142,20 @@ pymap_to_tv(PyObject *obj, typval_T *tv,
 	{
 	    vim_free(di);
 	    Py_DECREF(list);
-	    Py_DECREF(litem);
+	    Py_DECREF(valObject);
 	    return -1;
 	}
+
+	Py_DECREF(valObject);
+
 	if (dict_add(dict, di) == FAIL)
 	{
+	    clear_tv(&di->di_tv);
 	    vim_free(di);
 	    Py_DECREF(list);
-	    Py_DECREF(litem);
 	    PyErr_SetVim(_("failed to add key to dictionary"));
 	    return -1;
 	}
-	Py_DECREF(litem);
     }
     Py_DECREF(list);
     return 0;
@@ -4201,13 +4210,18 @@ pyiter_to_tv(PyObject *obj, typval_T *tv
 	li = listitem_alloc();
 	if (li == NULL)
 	{
+	    Py_DECREF(iterator);
 	    PyErr_NoMemory();
 	    return -1;
 	}
 	li->li_tv.v_lock = 0;
 
 	if (_ConvertFromPyObject(item, &li->li_tv, lookup_dict) == -1)
+	{
+	    Py_DECREF(item);
+	    Py_DECREF(iterator);
 	    return -1;
+	}
 
 	list_append(l, li);
 
@@ -4241,8 +4255,12 @@ convert_dl(PyObject *obj, typval_T *tv,
 # else
 	capsule = PyCObject_FromVoidPtr(tv, NULL);
 # endif
-	PyDict_SetItemString(lookup_dict, hexBuf, capsule);
-	Py_DECREF(capsule);
+	if (PyDict_SetItemString(lookup_dict, hexBuf, capsule))
+	{
+	    Py_DECREF(capsule);
+	    tv->v_type = VAR_UNKNOWN;
+	    return -1;
+	}
 	if (py_to_tv(obj, tv, lookup_dict) == -1)
 	{
 	    tv->v_type = VAR_UNKNOWN;
--- a/src/version.c
+++ b/src/version.c
@@ -729,6 +729,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    1051,
+/**/
     1050,
 /**/
     1049,