# HG changeset patch # User Bram Moolenaar # Date 1546114505 -3600 # Node ID 5bfdce4de97ff5fc6fcd61cde506eddc25b76fd7 # Parent 6d4c7811e078e4dd3226c13e6bb4f55895c730f2 patch 8.1.0660: sign_cleanup() may leak memory commit https://github.com/vim/vim/commit/1ea88a3e12e5f6afc5353cd0d6e6d4f4a89ced94 Author: Bram Moolenaar Date: Sat Dec 29 21:00:27 2018 +0100 patch 8.1.0660: sign_cleanup() may leak memory Problem: sign_cleanup() may leak memory. Solution: Free the group name before returning. Add a few more tests. (Yegappan Lakshmanan) diff --git a/src/evalfunc.c b/src/evalfunc.c --- a/src/evalfunc.c +++ b/src/evalfunc.c @@ -11578,7 +11578,7 @@ f_sign_unplace(typval_T *argvars, typval if (argvars[1].v_type != VAR_DICT) { EMSG(_(e_dictreq)); - return; + goto cleanup; } dict = argvars[1].vval.v_dict; @@ -11589,7 +11589,7 @@ f_sign_unplace(typval_T *argvars, typval { EMSG2(_("E158: Invalid buffer name: %s"), tv_get_string(&di->di_tv)); - return; + goto cleanup; } } if (dict_find(dict, (char_u *)"id", -1) != NULL) @@ -11608,6 +11608,8 @@ f_sign_unplace(typval_T *argvars, typval if (sign_unplace(sign_id, group, buf, 0) == OK) rettv->vval.v_number = 0; } + +cleanup: vim_free(group); } #endif diff --git a/src/testdir/test_signs.vim b/src/testdir/test_signs.vim --- a/src/testdir/test_signs.vim +++ b/src/testdir/test_signs.vim @@ -385,6 +385,8 @@ func Test_sign_funcs() \ {"lnum" : -1})', 'E885:') call assert_fails('call sign_place(22, "", "sign1", "Xsign", \ {"lnum" : 0})', 'E885:') + call assert_fails('call sign_place(22, "", "sign1", "Xsign", + \ {"lnum" : []})', 'E745:') call assert_equal(-1, sign_place(1, "*", "sign1", "Xsign", {"lnum" : 10})) " Tests for sign_getplaced() @@ -420,9 +422,9 @@ func Test_sign_funcs() \ {'id' : 20, 'buffer' : 'buffer.c'})", 'E158:') call assert_fails("call sign_unplace('', \ {'id' : 20, 'buffer' : ''})", 'E158:') - call assert_fails("call sign_unplace('', + call assert_fails("call sign_unplace('g1', \ {'id' : 20, 'buffer' : 200})", 'E158:') - call assert_fails("call sign_unplace('', 'mySign')", 'E715:') + call assert_fails("call sign_unplace('g1', 'mySign')", 'E715:') " Tests for sign_undefine() call assert_equal(0, sign_undefine("sign1")) @@ -664,7 +666,7 @@ func Test_sign_group() call delete("Xsign") call sign_unplace('*') call sign_undefine() - enew | only + enew | only endfunc " Place signs used for ":sign unplace" command test @@ -1013,7 +1015,7 @@ func Test_sign_unplace() call sign_unplace('*') call sign_undefine() - enew | only + enew | only call delete("Xsign1") call delete("Xsign2") endfunc @@ -1042,6 +1044,9 @@ func Test_sign_id_autogen() call assert_equal(1, sign_place(0, 'g1', 'sign1', 'Xsign', \ {'lnum' : 11})) + " Check for the next generated sign id in this group + call assert_equal(2, sign_place(0, 'g1', 'sign1', 'Xsign', + \ {'lnum' : 12})) call assert_equal(0, sign_unplace('g1', {'id' : 1})) call assert_equal(10, \ sign_getplaced('Xsign', {'id' : 1})[0].signs[0].lnum) @@ -1049,7 +1054,7 @@ func Test_sign_id_autogen() call delete("Xsign") call sign_unplace('*') call sign_undefine() - enew | only + enew | only endfunc " Test for sign priority @@ -1085,6 +1090,8 @@ func Test_sign_priority() " Error case call assert_fails("call sign_place(1, 'g1', 'sign1', 'Xsign', \ [])", 'E715:') + call assert_fails("call sign_place(1, 'g1', 'sign1', 'Xsign', + \ {'priority' : []})", 'E745:') call sign_unplace('*') " Tests for the :sign place command with priority @@ -1104,7 +1111,7 @@ func Test_sign_priority() call sign_unplace('*') call sign_undefine() - enew | only + enew | only call delete("Xsign") endfunc @@ -1146,6 +1153,6 @@ func Test_sign_memfailures() call sign_unplace('*') call sign_undefine() - enew | only + enew | only call delete("Xsign") endfunc diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -800,6 +800,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 660, +/**/ 659, /**/ 658,