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.