patch 9.1.0261: Vim9: protected class and funcrefs accessible outside the class

Commit: 
https://github.com/vim/vim/commit/3e33650b3a9939f6b942c1d1eccdb261ea17a647
Author: Yegappan Lakshmanan <yegap...@yahoo.com>
Date:   Thu Apr 4 19:35:59 2024 +0200

    patch 9.1.0261: Vim9: protected class and funcrefs accessible outside the 
class
    
    Problem:  Vim9: protected class and funcrefs accessible outside the class
              (Aliaksei Budavei)
    Solution: Check if class and object funcrefs are protected
              (Yegappan)
    
    closes: #14407
    
    Signed-off-by: Yegappan Lakshmanan <yegap...@yahoo.com>
    Signed-off-by: Christian Brabandt <c...@256bit.org>

diff --git a/src/testdir/test_functions.vim b/src/testdir/test_functions.vim
index fecebc49d..f0d738582 100644
--- a/src/testdir/test_functions.vim
+++ b/src/testdir/test_functions.vim
@@ -3794,6 +3794,43 @@ func Test_funcref_to_string()
   call assert_equal("function('g:Test_funcref_to_string')", string(Fn))
 endfunc
 
+" A funcref cannot start with an underscore (except when used as a protected
+" class or object variable)
+func Test_funcref_with_underscore()
+  " at script level
+  let lines =<< trim END
+    vim9script
+    var _Fn = () => 10
+  END
+  call v9.CheckSourceFailure(lines, 'E704: Funcref variable name must start 
with a capital: _Fn')
+
+  " inside a function
+  let lines =<< trim END
+    vim9script
+    def Func()
+      var _Fn = () => 10
+    enddef
+    defcompile
+  END
+  call v9.CheckSourceFailure(lines, 'E704: Funcref variable name must start 
with a capital: _Fn', 1)
+
+  " as a function argument
+  let lines =<< trim END
+    vim9script
+    def Func(_Fn: func)
+    enddef
+    defcompile
+  END
+  call v9.CheckSourceFailure(lines, 'E704: Funcref variable name must start 
with a capital: _Fn', 2)
+
+  " as a lambda argument
+  let lines =<< trim END
+    vim9script
+    var Fn = (_Farg: func) => 10
+  END
+  call v9.CheckSourceFailure(lines, 'E704: Funcref variable name must start 
with a capital: _Farg', 2)
+endfunc
+
 " Test for isabsolutepath()
 func Test_isabsolutepath()
   call assert_false(isabsolutepath(''))
diff --git a/src/testdir/test_vim9_class.vim b/src/testdir/test_vim9_class.vim
index 93481d55b..6eafe0037 100644
--- a/src/testdir/test_vim9_class.vim
+++ b/src/testdir/test_vim9_class.vim
@@ -10530,4 +10530,27 @@ def 
Test_use_base_class_variable_from_base_class_method()
   v9.CheckScriptSuccess(lines)
 enddef
 
+" Test for accessing protected funcref object and class variables
+def Test_protected_funcref()
+  # protected funcref object variable
+  var lines =<< trim END
+    vim9script
+    class Test1
+      const _Id: func(any): any = (v) => v
+    endclass
+    var n = Test1.new()._Id(1)
+  END
+  v9.CheckScriptFailure(lines, 'E1333: Cannot access protected variable "_Id" 
in class "Test1"', 5)
+
+  # protected funcref class variable
+  lines =<< trim END
+    vim9script
+    class Test2
+      static const _Id: func(any): any = (v) => v
+    endclass
+    var n = Test2._Id(2)
+  END
+  v9.CheckScriptFailure(lines, 'E1333: Cannot access protected variable "_Id" 
in class "Test2"', 5)
+enddef
+
 " vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
diff --git a/src/userfunc.c b/src/userfunc.c
index ce144a397..9a307966b 100644
--- a/src/userfunc.c
+++ b/src/userfunc.c
@@ -570,10 +570,16 @@ parse_argument_types(
                fp->uf_arg_types[i] = type;
                if (i < fp->uf_args.ga_len
                        && (type->tt_type == VAR_FUNC
-                           || type->tt_type == VAR_PARTIAL)
-                       && var_wrong_func_name(
-                                   ((char_u **)fp->uf_args.ga_data)[i], TRUE))
-                   return FAIL;
+                           || type->tt_type == VAR_PARTIAL))
+               {
+                   char_u *name = ((char_u **)fp->uf_args.ga_data)[i];
+                   if (obj_members != NULL && *name == '_')
+                       // protected object method
+                       name++;
+
+                   if (var_wrong_func_name(name, TRUE))
+                       return FAIL;
+               }
            }
        }
     }
diff --git a/src/version.c b/src/version.c
index eef06c66e..450e0d8cf 100644
--- a/src/version.c
+++ b/src/version.c
@@ -704,6 +704,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    261,
 /**/
     260,
 /**/
diff --git a/src/vim9class.c b/src/vim9class.c
index fc4e00285..11e952c79 100644
--- a/src/vim9class.c
+++ b/src/vim9class.c
@@ -2835,6 +2835,14 @@ call_oc_method(
            return FAIL;
        }
 
+       if (*name == '_')
+       {
+           // Protected object or class funcref variable
+           semsg(_(e_cannot_access_protected_variable_str), ocm->ocm_name,
+                   cl->class_name);
+           return FAIL;
+       }
+
        if (rettv->v_type == VAR_OBJECT)
        {
            // funcref object variable

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to vim_dev+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/E1rsR9D-008KKn-60%40256bit.org.

Reply via email to