forked from aniani/vim
patch 8.0.1647: terminal API may call any user function
Problem: Terminal API may call a function not meant to be called by this API. Solution: Require the function to start with Tapi_.
This commit is contained in:
@@ -423,20 +423,26 @@ Currently supported commands:
|
|||||||
|
|
||||||
call {funcname} {argument}
|
call {funcname} {argument}
|
||||||
|
|
||||||
Call a user defined function with [argument]. The function is
|
Call a user defined function with {argument}.
|
||||||
called with the buffer number of the terminal and the decoded
|
The function is called with two arguments: the buffer number
|
||||||
argument. The user function must sanity check the argument.
|
of the terminal and {argument}, the decoded JSON argument.
|
||||||
|
The function name must start with "Tapi_" to avoid
|
||||||
|
accidentally calling a function not meant to be used for the
|
||||||
|
terminal API
|
||||||
|
The user function should sanity check the argument.
|
||||||
The function can use |term_sendkeys()| to send back a reply.
|
The function can use |term_sendkeys()| to send back a reply.
|
||||||
Example in JSON: >
|
Example in JSON: >
|
||||||
["call", "Impression", ["play", 14]]
|
["call", "Tapi_Impression", ["play", 14]]
|
||||||
< Calls a function defined like this: >
|
< Calls a function defined like this: >
|
||||||
function Impression(bufnum, arglist)
|
function Tapi_Impression(bufnum, arglist)
|
||||||
if len(a:arglist) == 2
|
if len(a:arglist) == 2
|
||||||
echo "impression " . a:arglist[0]
|
echomsg "impression " . a:arglist[0]
|
||||||
echo "count " . a:arglist[1]
|
echomsg "count " . a:arglist[1]
|
||||||
endif
|
endif
|
||||||
endfunc
|
endfunc
|
||||||
<
|
< Output from `:echo` may be erased by a redraw, use `:echomsg`
|
||||||
|
to be able to see it with `:messages`.
|
||||||
|
|
||||||
drop {filename}
|
drop {filename}
|
||||||
|
|
||||||
Let Vim open a file, like the `:drop` command. If {filename}
|
Let Vim open a file, like the `:drop` command. If {filename}
|
||||||
@@ -447,7 +453,7 @@ Currently supported commands:
|
|||||||
|
|
||||||
A trick to have Vim send this escape sequence: >
|
A trick to have Vim send this escape sequence: >
|
||||||
exe "set t_ts=\<Esc>]51; t_fs=\x07"
|
exe "set t_ts=\<Esc>]51; t_fs=\x07"
|
||||||
let &titlestring = '["call","TryThis",["hello",123]]'
|
let &titlestring = '["call","Tapi_TryThis",["hello",123]]'
|
||||||
redraw
|
redraw
|
||||||
set t_ts& t_fs&
|
set t_ts& t_fs&
|
||||||
|
|
||||||
|
@@ -3193,7 +3193,7 @@ handle_call_command(term_T *term, channel_T *channel, listitem_T *item)
|
|||||||
}
|
}
|
||||||
func = get_tv_string(&item->li_tv);
|
func = get_tv_string(&item->li_tv);
|
||||||
|
|
||||||
if (!ASCII_ISUPPER(*func))
|
if (STRNCMP(func, "Tapi_", 5) != 0)
|
||||||
{
|
{
|
||||||
ch_log(channel, "Invalid function name: %s", func);
|
ch_log(channel, "Invalid function name: %s", func);
|
||||||
return;
|
return;
|
||||||
|
@@ -1072,24 +1072,28 @@ func Test_terminal_api_drop_oldwin()
|
|||||||
bwipe Xtextfile
|
bwipe Xtextfile
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
func TryThis(bufnum, arg)
|
func Tapi_TryThis(bufnum, arg)
|
||||||
let g:called_bufnum = a:bufnum
|
let g:called_bufnum = a:bufnum
|
||||||
let g:called_arg = a:arg
|
let g:called_arg = a:arg
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
func WriteApiCall(funcname)
|
||||||
|
" Use the title termcap entries to output the escape sequence.
|
||||||
|
call writefile([
|
||||||
|
\ 'set title',
|
||||||
|
\ 'exe "set t_ts=\<Esc>]51; t_fs=\x07"',
|
||||||
|
\ 'let &titlestring = ''["call","' . a:funcname . '",["hello",123]]''',
|
||||||
|
\ 'redraw',
|
||||||
|
\ "set t_ts=",
|
||||||
|
\ ], 'Xscript')
|
||||||
|
endfunc
|
||||||
|
|
||||||
func Test_terminal_api_call()
|
func Test_terminal_api_call()
|
||||||
if !CanRunVimInTerminal()
|
if !CanRunVimInTerminal()
|
||||||
return
|
return
|
||||||
endif
|
endif
|
||||||
|
|
||||||
" Use the title termcap entries to output the escape sequence.
|
call WriteApiCall('Tapi_TryThis')
|
||||||
call writefile([
|
|
||||||
\ 'set title',
|
|
||||||
\ 'exe "set t_ts=\<Esc>]51; t_fs=\x07"',
|
|
||||||
\ 'let &titlestring = ''["call","TryThis",["hello",123]]''',
|
|
||||||
\ 'redraw',
|
|
||||||
\ "set t_ts=",
|
|
||||||
\ ], 'Xscript')
|
|
||||||
let buf = RunVimInTerminal('-S Xscript', {})
|
let buf = RunVimInTerminal('-S Xscript', {})
|
||||||
call WaitFor({-> exists('g:called_bufnum')})
|
call WaitFor({-> exists('g:called_bufnum')})
|
||||||
call assert_equal(buf, g:called_bufnum)
|
call assert_equal(buf, g:called_bufnum)
|
||||||
@@ -1100,3 +1104,19 @@ func Test_terminal_api_call()
|
|||||||
unlet g:called_bufnum
|
unlet g:called_bufnum
|
||||||
unlet g:called_arg
|
unlet g:called_arg
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
func Test_terminal_api_call_fails()
|
||||||
|
if !CanRunVimInTerminal()
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
call WriteApiCall('TryThis')
|
||||||
|
call ch_logfile('Xlog', 'w')
|
||||||
|
let buf = RunVimInTerminal('-S Xscript', {})
|
||||||
|
call WaitFor({-> string(readfile('Xlog')) =~ 'Invalid function name: TryThis'})
|
||||||
|
|
||||||
|
call StopVimInTerminal(buf)
|
||||||
|
call delete('Xscript')
|
||||||
|
call ch_logfile('', '')
|
||||||
|
call delete('Xlog')
|
||||||
|
endfunc
|
||||||
|
@@ -766,6 +766,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
1647,
|
||||||
/**/
|
/**/
|
||||||
1646,
|
1646,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user