summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2022-03-08 16:52:24 +0000
committerBram Moolenaar <Bram@vim.org>2022-03-08 16:52:24 +0000
commit673bcb10ebe87ccf6954dd342d0143eb88cdfbcb (patch)
treeeb710ec734800e99a795c8be85e1c9440c5474ab
parent0b40d086b337f14fdd0dbc035988ffb0aec8ce5f (diff)
downloadvim-git-8.2.4528.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.vim9
-rw-r--r--src/userfunc.c17
-rw-r--r--src/version.c2
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,