]> granicus.if.org Git - vim/commitdiff
updated for version 7.3.1056 v7.3.1056
authorBram Moolenaar <Bram@vim.org>
Thu, 30 May 2013 10:14:49 +0000 (12:14 +0200)
committerBram Moolenaar <Bram@vim.org>
Thu, 30 May 2013 10:14:49 +0000 (12:14 +0200)
Problem:    Python: possible memory leaks.
Solution:   Python patch 15. (ZyX) Fix will follow later.

src/eval.c
src/if_py_both.h
src/proto/eval.pro
src/version.c

index 756baa39b89736e1c836eadaa8be8b36f04cd8d3..a07b6d6d4a301db016d7671e903db40a70c94766 100644 (file)
@@ -412,7 +412,6 @@ static int get_string_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate));
 static int get_lit_string_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate));
 static int get_list_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate));
 static int rettv_list_alloc __ARGS((typval_T *rettv));
-static void listitem_free __ARGS((listitem_T *item));
 static long list_len __ARGS((list_T *l));
 static int list_equal __ARGS((list_T *l1, list_T *l2, int ic, int recursive));
 static int dict_equal __ARGS((dict_T *d1, dict_T *d2, int ic, int recursive));
@@ -428,7 +427,6 @@ static int list_join_inner __ARGS((garray_T *gap, list_T *l, char_u *sep, int ec
 static int list_join __ARGS((garray_T *gap, list_T *l, char_u *sep, int echo, int copyID));
 static int free_unref_items __ARGS((int copyID));
 static int rettv_dict_alloc __ARGS((typval_T *rettv));
-static void dict_free __ARGS((dict_T *d, int recurse));
 static dictitem_T *dictitem_copy __ARGS((dictitem_T *org));
 static void dictitem_remove __ARGS((dict_T *dict, dictitem_T *item));
 static dict_T *dict_copy __ARGS((dict_T *orig, int deep, int copyID));
@@ -5955,7 +5953,7 @@ listitem_alloc()
 /*
  * Free a list item.  Also clears the value.  Does not notify watchers.
  */
-    static void
+    void
 listitem_free(item)
     listitem_T *item;
 {
@@ -7031,7 +7029,7 @@ dict_unref(d)
  * Free a Dictionary, including all items it contains.
  * Ignores the reference count.
  */
-    static void
+    void
 dict_free(d, recurse)
     dict_T  *d;
     int            recurse;    /* Free Lists and Dictionaries recursively. */
@@ -8353,7 +8351,7 @@ get_func_tv(name, len, rettv, arg, firstline, lastline, doesrange,
 
 /*
  * Call a function with its resolved parameters
- * Return OK when the function can't be called,  FAIL otherwise.
+ * Return FAIL when the function can't be called,  OK otherwise.
  * Also returns OK when an error was encountered while executing the function.
  */
     static int
index 088bc5e744d9b6fd4e2e455800fc0aee8ac76b6c..2ad19c4062255b502b1610ac5bd3f045b6f3a1d2 100644 (file)
@@ -32,8 +32,15 @@ typedef int Py_ssize_t;  /* Python 2.4 and earlier don't have this type. */
 
 #define DICTKEY_DECL \
     PyObject   *dictkey_todecref;
+#define DICTKEY_CHECK_EMPTY(err) \
+    if (*key == NUL) \
+    { \
+       PyErr_SetString(PyExc_ValueError, _("empty keys are not allowed")); \
+       return err; \
+    }
+#define DICTKEY_SET_KEY (key = StringToChars(keyObject, &dictkey_todecref))
 #define DICTKEY_GET(err, decref) \
-    if (!(key = StringToChars(keyObject, &dictkey_todecref))) \
+    if (!DICTKEY_SET_KEY) \
     { \
        if (decref) \
        { \
@@ -43,11 +50,7 @@ typedef int Py_ssize_t;  /* Python 2.4 and earlier don't have this type. */
     } \
     if (decref && !dictkey_todecref) \
        dictkey_todecref = keyObject; \
-    if (*key == NUL) \
-    { \
-       PyErr_SetString(PyExc_ValueError, _("empty keys are not allowed")); \
-       return err; \
-    }
+    DICTKEY_CHECK_EMPTY(err)
 #define DICTKEY_UNREF \
     Py_XDECREF(dictkey_todecref);
 
@@ -651,9 +654,13 @@ VimEval(PyObject *self UNUSED, PyObject *args)
 
     /* Convert the Vim type into a Python type.  Create a dictionary that's
      * used to check for recursive loops. */
-    lookup_dict = PyDict_New();
-    result = VimToPython(our_tv, 1, lookup_dict);
-    Py_DECREF(lookup_dict);
+    if (!(lookup_dict = PyDict_New()))
+       result = NULL;
+    else
+    {
+       result = VimToPython(our_tv, 1, lookup_dict);
+       Py_DECREF(lookup_dict);
+    }
 
 
     Py_BEGIN_ALLOW_THREADS
@@ -1401,7 +1408,9 @@ ListConcatInPlace(ListObject *self, PyObject *obj)
        return NULL;
     }
 
-    lookup_dict = PyDict_New();
+    if (!(lookup_dict = PyDict_New()))
+       return NULL;
+
     if (list_py_concat(l, obj, lookup_dict) == -1)
     {
        Py_DECREF(lookup_dict);
@@ -4023,12 +4032,8 @@ pydict_to_tv(PyObject *obj, typval_T *tv, PyObject *lookup_dict)
     PyObject   *valObject;
     Py_ssize_t iter = 0;
 
-    dict = dict_alloc();
-    if (dict == NULL)
-    {
-       PyErr_NoMemory();
+    if (!(dict = dict_alloc()))
        return -1;
-    }
 
     tv->v_type = VAR_DICT;
     tv->vval.v_dict = dict;
@@ -4038,9 +4043,17 @@ pydict_to_tv(PyObject *obj, typval_T *tv, PyObject *lookup_dict)
        DICTKEY_DECL
 
        if (keyObject == NULL || valObject == NULL)
+       {
+           dict_unref(dict);
            return -1;
+       }
 
-       DICTKEY_GET(-1, 0)
+       if (!DICTKEY_SET_KEY)
+       {
+           dict_unref(dict);
+           return -1;
+       }
+       DICTKEY_CHECK_EMPTY(-1)
 
        di = dictitem_alloc(key);
 
@@ -4049,6 +4062,7 @@ pydict_to_tv(PyObject *obj, typval_T *tv, PyObject *lookup_dict)
        if (di == NULL)
        {
            PyErr_NoMemory();
+           dict_unref(dict);
            return -1;
        }
        di->di_tv.v_lock = 0;
@@ -4056,6 +4070,7 @@ pydict_to_tv(PyObject *obj, typval_T *tv, PyObject *lookup_dict)
        if (_ConvertFromPyObject(valObject, &di->di_tv, lookup_dict) == -1)
        {
            vim_free(di);
+           dict_unref(dict);
            return -1;
        }
 
@@ -4063,10 +4078,13 @@ pydict_to_tv(PyObject *obj, typval_T *tv, PyObject *lookup_dict)
        {
            clear_tv(&di->di_tv);
            vim_free(di);
+           dict_unref(dict);
            PyErr_SetVim(_("failed to add key to dictionary"));
            return -1;
        }
     }
+
+    --dict->dv_refcount;
     return 0;
 }
 
@@ -4082,19 +4100,18 @@ pymap_to_tv(PyObject *obj, typval_T *tv, PyObject *lookup_dict)
     PyObject   *valObject;
     Py_ssize_t lsize;
 
-    dict = dict_alloc();
-    if (dict == NULL)
-    {
-       PyErr_NoMemory();
+    if (!(dict = dict_alloc()))
        return -1;
-    }
 
     tv->v_type = VAR_DICT;
     tv->vval.v_dict = dict;
 
     list = PyMapping_Items(obj);
     if (list == NULL)
+    {
+       dict_unref(dict);
        return -1;
+    }
     lsize = PyList_Size(list);
     while (lsize--)
     {
@@ -4104,6 +4121,7 @@ pymap_to_tv(PyObject *obj, typval_T *tv, PyObject *lookup_dict)
        if (litem == NULL)
        {
            Py_DECREF(list);
+           dict_unref(dict);
            return -1;
        }
 
@@ -4111,15 +4129,25 @@ pymap_to_tv(PyObject *obj, typval_T *tv, PyObject *lookup_dict)
        {
            Py_DECREF(list);
            Py_DECREF(litem);
+           dict_unref(dict);
            return -1;
        }
 
-       DICTKEY_GET(-1, 1)
+       if (!DICTKEY_SET_KEY)
+       {
+           dict_unref(dict);
+           Py_DECREF(list);
+           Py_DECREF(litem);
+           DICTKEY_UNREF
+           return -1;
+       }
+       DICTKEY_CHECK_EMPTY(-1)
 
        if (!(valObject = PyTuple_GetItem(litem, 1)))
        {
            Py_DECREF(list);
            Py_DECREF(litem);
+           dict_unref(dict);
            DICTKEY_UNREF
            return -1;
        }
@@ -4133,7 +4161,7 @@ pymap_to_tv(PyObject *obj, typval_T *tv, PyObject *lookup_dict)
        if (di == NULL)
        {
            Py_DECREF(list);
-           Py_DECREF(valObject);
+           dict_unref(dict);
            PyErr_NoMemory();
            return -1;
        }
@@ -4142,75 +4170,87 @@ pymap_to_tv(PyObject *obj, typval_T *tv, PyObject *lookup_dict)
        if (_ConvertFromPyObject(valObject, &di->di_tv, lookup_dict) == -1)
        {
            vim_free(di);
+           dict_unref(dict);
            Py_DECREF(list);
-           Py_DECREF(valObject);
            return -1;
        }
 
-       Py_DECREF(valObject);
-
        if (dict_add(dict, di) == FAIL)
        {
-           clear_tv(&di->di_tv);
-           vim_free(di);
+           dictitem_free(di);
+           dict_unref(dict);
            Py_DECREF(list);
            PyErr_SetVim(_("failed to add key to dictionary"));
            return -1;
        }
     }
+    --dict->dv_refcount;
     Py_DECREF(list);
     return 0;
 }
 
+    static list_T *
+py_list_alloc()
+{
+    list_T     *r;
+
+    if (!(r = list_alloc()))
+    {
+       PyErr_NoMemory();
+       return NULL;
+    }
+    ++r->lv_refcount;
+
+    return r;
+}
+
     static int
 pyseq_to_tv(PyObject *obj, typval_T *tv, PyObject *lookup_dict)
 {
     list_T     *l;
 
-    l = list_alloc();
-    if (l == NULL)
-    {
-       PyErr_NoMemory();
+    if (!(l = py_list_alloc()))
        return -1;
-    }
 
     tv->v_type = VAR_LIST;
     tv->vval.v_list = l;
 
     if (list_py_concat(l, obj, lookup_dict) == -1)
+    {
+       list_unref(l);
        return -1;
+    }
 
+    --l->lv_refcount;
     return 0;
 }
 
     static int
 pyiter_to_tv(PyObject *obj, typval_T *tv, PyObject *lookup_dict)
 {
-    PyObject   *iterator = PyObject_GetIter(obj);
+    PyObject   *iterator;
     PyObject   *item;
     list_T     *l;
     listitem_T *li;
 
-    l = list_alloc();
-
-    if (l == NULL)
-    {
-       PyErr_NoMemory();
+    if (!(l = py_list_alloc()))
        return -1;
-    }
 
     tv->vval.v_list = l;
     tv->v_type = VAR_LIST;
 
-
-    if (iterator == NULL)
+    if (!(iterator = PyObject_GetIter(obj)))
+    {
+       list_unref(l);
        return -1;
+    }
 
     while ((item = PyIter_Next(iterator)))
     {
        li = listitem_alloc();
        if (li == NULL)
        {
+           list_unref(l);
            Py_DECREF(iterator);
            PyErr_NoMemory();
            return -1;
@@ -4219,6 +4259,8 @@ pyiter_to_tv(PyObject *obj, typval_T *tv, PyObject *lookup_dict)
 
        if (_ConvertFromPyObject(item, &li->li_tv, lookup_dict) == -1)
        {
+           list_unref(l);
+           listitem_free(li);
            Py_DECREF(item);
            Py_DECREF(iterator);
            return -1;
@@ -4230,6 +4272,15 @@ pyiter_to_tv(PyObject *obj, typval_T *tv, PyObject *lookup_dict)
     }
 
     Py_DECREF(iterator);
+
+    /* Iterator may have finished due to an exception */
+    if (PyErr_Occurred())
+    {
+       list_unref(l);
+       return -1;
+    }
+
+    --l->lv_refcount;
     return 0;
 }
 
@@ -4295,7 +4346,8 @@ ConvertFromPyObject(PyObject *obj, typval_T *tv)
     PyObject   *lookup_dict;
     int                r;
 
-    lookup_dict = PyDict_New();
+    if (!(lookup_dict = PyDict_New()))
+       return -1;
     r = _ConvertFromPyObject(obj, tv, lookup_dict);
     Py_DECREF(lookup_dict);
     return r;
index dfea118999cebdc82b38b509bdc86417e22aa036..6d46ebd379056dbe6a3e1286e9050967c0a3985b 100644 (file)
@@ -49,6 +49,7 @@ list_T *list_alloc __ARGS((void));
 void list_unref __ARGS((list_T *l));
 void list_free __ARGS((list_T *l, int recurse));
 listitem_T *listitem_alloc __ARGS((void));
+void listitem_free __ARGS((listitem_T *item));
 void listitem_remove __ARGS((list_T *l, listitem_T *item));
 dictitem_T *dict_lookup __ARGS((hashitem_T *hi));
 listitem_T *list_find __ARGS((list_T *l, long n));
@@ -65,6 +66,7 @@ void set_ref_in_list __ARGS((list_T *l, int copyID));
 void set_ref_in_item __ARGS((typval_T *tv, int copyID));
 dict_T *dict_alloc __ARGS((void));
 void dict_unref __ARGS((dict_T *d));
+void dict_free __ARGS((dict_T *d, int recurse));
 dictitem_T *dictitem_alloc __ARGS((char_u *key));
 void dictitem_free __ARGS((dictitem_T *item));
 int dict_add __ARGS((dict_T *d, dictitem_T *item));
index 651c64c588208440cd4026a5021628ed9bffcb71..c33c1a687876c098a856142234a9a696883c5518 100644 (file)
@@ -728,6 +728,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1056,
 /**/
     1055,
 /**/