Patch 7.4.1639
Problem: Invoking garbage collection may cause a double free.
Solution: Don't free the dict in a partial when recursive is FALSE.
Files: src/eval.c
*** ../vim-7.4.1638/src/eval.c 2016-03-22 21:00:06.052953785 +0100
--- src/eval.c 2016-03-22 22:22:09.045823705 +0100
***************
*** 209,215 ****
/* The names of packages that once were loaded are remembered. */
static garray_T ga_loaded = {0, 0, sizeof(char_u *), 4, NULL};
! /* list heads for garbage collection */
static dict_T *first_dict = NULL; /* list of all dicts */
static list_T *first_list = NULL; /* list of all lists */
--- 209,217 ----
/* The names of packages that once were loaded are remembered. */
static garray_T ga_loaded = {0, 0, sizeof(char_u *), 4, NULL};
! /* List heads for garbage collection. Although there can be a reference loop
! * from partial to dict to partial, we don't need to keep track of the
partial,
! * since it will get freed when the dict is unused and gets freed. */
static dict_T *first_dict = NULL; /* list of all dicts */
static list_T *first_list = NULL; /* list of all lists */
***************
*** 7130,7138 ****
list_T *ll;
int abort = FALSE;
! if (tv->v_type == VAR_DICT)
{
! dd = tv->vval.v_dict;
if (dd != NULL && dd->dv_copyID != copyID)
{
/* Didn't see this dict yet. */
--- 7132,7145 ----
list_T *ll;
int abort = FALSE;
! if (tv->v_type == VAR_DICT || tv->v_type == VAR_PARTIAL)
{
! if (tv->v_type == VAR_DICT)
! dd = tv->vval.v_dict;
! else if (tv->vval.v_partial != NULL)
! dd = tv->vval.v_partial->pt_dict;
! else
! dd = NULL;
if (dd != NULL && dd->dv_copyID != copyID)
{
/* Didn't see this dict yet. */
***************
*** 7184,7189 ****
--- 7191,7222 ----
return abort;
}
+ static void
+ partial_free(partial_T *pt, int free_dict)
+ {
+ int i;
+
+ for (i = 0; i < pt->pt_argc; ++i)
+ clear_tv(&pt->pt_argv[i]);
+ vim_free(pt->pt_argv);
+ if (free_dict)
+ dict_unref(pt->pt_dict);
+ func_unref(pt->pt_name);
+ vim_free(pt->pt_name);
+ vim_free(pt);
+ }
+
+ /*
+ * Unreference a closure: decrement the reference count and free it when it
+ * becomes zero.
+ */
+ void
+ partial_unref(partial_T *pt)
+ {
+ if (pt != NULL && --pt->pt_refcount <= 0)
+ partial_free(pt, TRUE);
+ }
+
/*
* Allocate an empty header for a dictionary.
*/
***************
*** 7275,7281 ****
hash_remove(&d->dv_hashtab, hi);
if (recurse || (di->di_tv.v_type != VAR_LIST
&& di->di_tv.v_type != VAR_DICT))
! clear_tv(&di->di_tv);
vim_free(di);
--todo;
}
--- 7308,7325 ----
hash_remove(&d->dv_hashtab, hi);
if (recurse || (di->di_tv.v_type != VAR_LIST
&& di->di_tv.v_type != VAR_DICT))
! {
! if (!recurse && di->di_tv.v_type == VAR_PARTIAL)
! {
! partial_T *pt = di->di_tv.vval.v_partial;
!
! /* We unref the partial but not the dict it refers to. */
! if (pt != NULL && --pt->pt_refcount == 0)
! partial_free(pt, FALSE);
! }
! else
! clear_tv(&di->di_tv);
! }
vim_free(di);
--todo;
}
***************
*** 12011,12041 ****
}
}
- static void
- partial_free(partial_T *pt)
- {
- int i;
-
- for (i = 0; i < pt->pt_argc; ++i)
- clear_tv(&pt->pt_argv[i]);
- vim_free(pt->pt_argv);
- dict_unref(pt->pt_dict);
- func_unref(pt->pt_name);
- vim_free(pt->pt_name);
- vim_free(pt);
- }
-
- /*
- * Unreference a closure: decrement the reference count and free it when it
- * becomes zero.
- */
- void
- partial_unref(partial_T *pt)
- {
- if (pt != NULL && --pt->pt_refcount <= 0)
- partial_free(pt);
- }
-
/*
* "garbagecollect()" function
*/
--- 12055,12060 ----
*** ../vim-7.4.1638/src/version.c 2016-03-22 21:00:06.052953785 +0100
--- src/version.c 2016-03-22 22:32:46.835179866 +0100
***************
*** 750,751 ****
--- 750,753 ----
{ /* Add new patch number below this line */
+ /**/
+ 1639,
/**/
--
hundred-and-one symptoms of being an internet addict:
99. The hum of a cooling fan and the click of keys is comforting to you.
/// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ an exciting new programming language -- http://www.Zimbu.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.