changeset 28006:02f787034998 v8.2.4528

patch 8.2.4528: crash when using null_function for a partial Commit: https://github.com/vim/vim/commit/673bcb10ebe87ccf6954dd342d0143eb88cdfbcb Author: Bram Moolenaar <Bram@vim.org> Date: Tue Mar 8 16:52:24 2022 +0000 patch 8.2.4528: crash when using null_function for a partial Problem: Crash when using null_function for a partial. Solution: Don't call fname_trans_sid() with NULL. (closes https://github.com/vim/vim/issues/9908)
author Bram Moolenaar <Bram@vim.org>
date Tue, 08 Mar 2022 18:00:04 +0100
parents 8e6476e5578c
children e11bea0167bb
files src/testdir/test_vim9_func.vim src/userfunc.c src/version.c
diffstat 3 files changed, 24 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- 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()
--- 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
     {
 	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 (fp != NULL && (fp->uf_flags & FC_DICT))
+	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))
+		|| (rettv->v_type == VAR_FUNC && rettv->vval.v_string == NULL))
     {
 	partial_T	*pt = ALLOC_CLEAR_ONE(partial_T);
 
--- 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,