diff options
author | Eliseo Martínez <eliseomarmol@gmail.com> | 2014-11-17 10:05:08 +0100 |
---|---|---|
committer | Eliseo Martínez <eliseomarmol@gmail.com> | 2014-11-18 22:00:01 +0100 |
commit | eb15d8777be0fe9a044b153a5f0991e1eb90faa9 (patch) | |
tree | 9aea454e64da8a30145930828f47a1025187e199 | |
parent | ece19651c60c34e2fa5bed623dff82b9af4d8e11 (diff) | |
download | rneovim-eb15d8777be0fe9a044b153a5f0991e1eb90faa9.tar.gz rneovim-eb15d8777be0fe9a044b153a5f0991e1eb90faa9.tar.bz2 rneovim-eb15d8777be0fe9a044b153a5f0991e1eb90faa9.zip |
Fix warnings: eval.c: clear_tv(): Bad free: RI.
Problem : Bad free @ 16076.
Diagnostic : Real issue.
Rationale : A non-allocated string is set at 4127, which later on can
be tried to be freed if aborting.
Resolution : Detect particular case (func with empty name) and don't
free in that case.
Another solution (use allocated string) was tried before,
but it produced a leak difficult to solve.
Finally applied solution works, but it produces a new false
positive warning (Np dereference at 13763), deactivated by
`assert(ptrs[i].item->li_next)`.
-rw-r--r-- | src/nvim/eval.c | 11 |
1 files changed, 9 insertions, 2 deletions
diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 44ea2b2332..b8d1799e9a 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -178,6 +178,8 @@ static char *e_nofunc = N_("E130: Unknown function: %s"); static char *e_illvar = N_("E461: Illegal variable name: %s"); static char *e_float_as_string = N_("E806: using Float as a String"); +static char_u * const empty_string = (char_u *)""; + static dictitem_T globvars_var; /* variable used for g: */ #define globvarht globvardict.dv_hashtab @@ -4124,7 +4126,7 @@ eval7 ( * get_func_tv, but it's needed in handle_subscript() to parse * what follows. So set it here. */ if (rettv->v_type == VAR_UNKNOWN && !evaluate && **arg == '(') { - rettv->vval.v_string = (char_u *)""; + rettv->vval.v_string = empty_string; rettv->v_type = VAR_FUNC; } @@ -13799,6 +13801,7 @@ static void do_sort_uniq(typval_T *argvars, typval_T *rettv, bool sort) if (!item_compare_func_err) { while (--i >= 0) { + assert(ptrs[i].item->li_next); li = ptrs[i].item->li_next; ptrs[i].item->li_next = li->li_next; if (li->li_next != NULL) { @@ -16134,7 +16137,11 @@ void clear_tv(typval_T *varp) switch (varp->v_type) { case VAR_FUNC: func_unref(varp->vval.v_string); - /*FALLTHROUGH*/ + if (varp->vval.v_string != empty_string) { + free(varp->vval.v_string); + } + varp->vval.v_string = NULL; + break; case VAR_STRING: free(varp->vval.v_string); varp->vval.v_string = NULL; |