]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.1.0261: Vim9: protected class and funcrefs accessible outside the class v9.1.0261
authorYegappan Lakshmanan <yegappan@yahoo.com>
Thu, 4 Apr 2024 17:35:59 +0000 (19:35 +0200)
committerChristian Brabandt <cb@256bit.org>
Thu, 4 Apr 2024 17:35:59 +0000 (19:35 +0200)
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 <yegappan@yahoo.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
src/testdir/test_functions.vim
src/testdir/test_vim9_class.vim
src/userfunc.c
src/version.c
src/vim9class.c

index fecebc49da22417e7de85cb633a0b05a44d3b5f8..f0d738582506dc8af2bc726b783bb537e8e30948 100644 (file)
@@ -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(''))
index 93481d55b8a2ee128015df07133a158b3f234918..6eafe00373647ca8f50ca1d529a381692d6710c9 100644 (file)
@@ -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
index ce144a397816555bbcfae5d50cdbeed4ce5b5f38..9a307966b722e6cacbf2f8ebab7937cdf4b1c9f7 100644 (file)
@@ -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;
+               }
            }
        }
     }
index eef06c66ec2a8dd76386d71019469057dd07721c..450e0d8cfb20966d3f158b6feee96009d65edead 100644 (file)
@@ -704,6 +704,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    261,
 /**/
     260,
 /**/
index fc4e002857fbe2f089dffae19080e26b70b1852b..11e952c7979bd863df5e0836716fbd4345fa57c1 100644 (file)
@@ -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