let g:.foo = 1 let 1 to global variable foo. And this way can overwrite builtin functions.
Describe the bug
let g:.foo = 1 let 1 to global variable foo. And this way can overwrite builtin functions.
To Reproduce
let g:.trim = {x-> ' '..x..' '} echo '['..trim(' foo ')..']'
This get [ foo ].
Expected behavior
[foo]
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub, or unsubscribe.![]()
This is also wrong.
let g:['trim'] = {x-> ' '..x..' '} echo '['..trim(' foo ')..']'
—
This should fix the issue.
diff --git a/src/userfunc.c b/src/userfunc.c index f5d906302..e463d73cd 100644 --- a/src/userfunc.c +++ b/src/userfunc.c @@ -1436,6 +1436,12 @@ deref_func_name( cc = name[*lenp]; name[*lenp] = NUL; + + if (builtin_function(name, -1)) { + name[*lenp] = cc; + return name; + } + v = find_var(name, &ht, no_autoload); name[*lenp] = cc; if (v != NULL)
Besides that check, it should not even be possible to add that variable in g: or s:
Actually, we cannot use builtin_function(), because in lambda's using a lower case name is possible.
I prefer checking for the referencing to the symbol, Not checking for letting variables.
:let s:.foo = { -> 'foo' }
:echo s:foo()
Vim(let):E704: Funcref variable name must start with a capital: foo
:let g:s = s:
function! CallS(name)
return s:[a:name]()
endfunction
:let g:s.foo = { -> 'foo' }
:echo CallS('foo')
:help E704 says:
< *E704* *E705* *E707*
A Funcref variable must start with a capital, "s:", "w:", "t:" or "b:". You
can use "g:" but the following name must still start with a capital. You
cannot have both a Funcref variable and a function with the same name.
so, I think "s:" should be able to be followed by a lower letter.
And, I think that "s:" in this part should be changed to "l:"
3d9c4ee#diff-3452ba3ede8c12266b78c613c3171f5a19f42244731749b3bc60072cdf45be46R2687-R2688
as follows:
call assert_fails('let l:["trim"] = {x -> " " .. x}', 'E704:') call assert_fails('let l:.trim = {x -> " " .. x}', 'E704:')
—
—
—