To: vim_dev@googlegroups.com Subject: Patch 7.4.1639 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ 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 -- Bram@Moolenaar.net -- 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 ///