diff options
author | Bram Moolenaar <Bram@vim.org> | 2022-03-08 16:52:24 +0000 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2022-03-08 16:52:24 +0000 |
commit | 673bcb10ebe87ccf6954dd342d0143eb88cdfbcb (patch) | |
tree | eb710ec734800e99a795c8be85e1c9440c5474ab | |
parent | 0b40d086b337f14fdd0dbc035988ffb0aec8ce5f (diff) | |
download | vim-git-673bcb10ebe87ccf6954dd342d0143eb88cdfbcb.tar.gz |
patch 8.2.4528: crash when using null_function for a partialv8.2.4528
Problem: Crash when using null_function for a partial.
Solution: Don't call fname_trans_sid() with NULL. (closes #9908)
-rw-r--r-- | src/testdir/test_vim9_func.vim | 9 | ||||
-rw-r--r-- | src/userfunc.c | 17 | ||||
-rw-r--r-- | src/version.c | 2 |
3 files changed, 22 insertions, 6 deletions
diff --git a/src/testdir/test_vim9_func.vim b/src/testdir/test_vim9_func.vim index a47dbae27..131413b16 100644 --- a/src/testdir/test_vim9_func.vim +++ b/src/testdir/test_vim9_func.vim @@ -3337,6 +3337,15 @@ def Test_partial_double_nested() assert_equal(123, RefRef()) enddef +def Test_partial_null_function() + var lines =<< trim END + var d: dict<func> = {f: null_function} + var Ref = d.f + assert_equal('func', typename(Ref)) + END + v9.CheckDefAndScriptSuccess(lines) +enddef + " Using "idx" from a legacy global function does not work. " This caused a crash when called from legacy context. func Test_partial_call_fails() diff --git a/src/userfunc.c b/src/userfunc.c index 63bb3140a..f0abaee5f 100644 --- a/src/userfunc.c +++ b/src/userfunc.c @@ -5730,7 +5730,6 @@ func_has_abort( make_partial(dict_T *selfdict_in, typval_T *rettv) { char_u *fname; - char_u *tofree = NULL; ufunc_T *fp; char_u fname_buf[FLEN_FIXED + 1]; int error; @@ -5742,13 +5741,19 @@ make_partial(dict_T *selfdict_in, typval_T *rettv) { fname = rettv->v_type == VAR_FUNC ? rettv->vval.v_string : rettv->vval.v_partial->pt_name; - // Translate "s:func" to the stored function name. - fname = fname_trans_sid(fname, fname_buf, &tofree, &error); - fp = find_func(fname, FALSE); - vim_free(tofree); + if (fname != NULL) + { + char_u *tofree = NULL; + + // Translate "s:func" to the stored function name. + fname = fname_trans_sid(fname, fname_buf, &tofree, &error); + fp = find_func(fname, FALSE); + vim_free(tofree); + } } - if (fp != NULL && (fp->uf_flags & FC_DICT)) + if ((fp != NULL && (fp->uf_flags & FC_DICT)) + || (rettv->v_type == VAR_FUNC && rettv->vval.v_string == NULL)) { partial_T *pt = ALLOC_CLEAR_ONE(partial_T); diff --git a/src/version.c b/src/version.c index 794591003..f6aaa7955 100644 --- a/src/version.c +++ b/src/version.c @@ -751,6 +751,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 4528, +/**/ 4527, /**/ 4526, |