Mercurial > vim
changeset 34769:d4fb6ea26ae4 v9.1.0261
patch 9.1.0261: Vim9: protected class and funcrefs accessible outside the class
Commit: https://github.com/vim/vim/commit/3e33650b3a9939f6b942c1d1eccdb261ea17a647
Author: Yegappan Lakshmanan <yegappan@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 <yegappan@yahoo.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Thu, 04 Apr 2024 19:45:10 +0200 |
parents | 1faaf5fdbb06 |
children | f03486fc4b8c |
files | src/testdir/test_functions.vim src/testdir/test_vim9_class.vim src/userfunc.c src/version.c src/vim9class.c |
diffstat | 5 files changed, 80 insertions(+), 4 deletions(-) [+] |
line wrap: on
line diff
--- 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(''))
--- 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_ba 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
--- 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; + } } } }
--- a/src/version.c +++ b/src/version.c @@ -705,6 +705,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 261, +/**/ 260, /**/ 259,
--- 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