diff options
author | Bram Moolenaar <Bram@vim.org> | 2018-03-26 21:38:52 +0200 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2018-03-26 21:38:52 +0200 |
commit | 2a77d21f7893ba14e682a3c5891d606f117a3f36 (patch) | |
tree | a31c14cee7362eeac7d143a5090e465653fc118c | |
parent | 4368d5ce8a2fa16826d76eeb32347bbbb4fad2bc (diff) | |
download | vim-git-2a77d21f7893ba14e682a3c5891d606f117a3f36.tar.gz |
patch 8.0.1647: terminal API may call any user functionv8.0.1647
Problem: Terminal API may call a function not meant to be called by this
API.
Solution: Require the function to start with Tapi_.
-rw-r--r-- | runtime/doc/terminal.txt | 24 | ||||
-rw-r--r-- | src/terminal.c | 2 | ||||
-rw-r--r-- | src/testdir/test_terminal.vim | 34 | ||||
-rw-r--r-- | src/version.c | 2 |
4 files changed, 45 insertions, 17 deletions
diff --git a/runtime/doc/terminal.txt b/runtime/doc/terminal.txt index 0c47fb637..53dd946b1 100644 --- a/runtime/doc/terminal.txt +++ b/runtime/doc/terminal.txt @@ -423,20 +423,26 @@ Currently supported commands: call {funcname} {argument} - Call a user defined function with [argument]. The function is - called with the buffer number of the terminal and the decoded - argument. The user function must sanity check the argument. + Call a user defined function with {argument}. + The function is called with two arguments: the buffer number + 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. Example in JSON: > - ["call", "Impression", ["play", 14]] + ["call", "Tapi_Impression", ["play", 14]] < Calls a function defined like this: > - function Impression(bufnum, arglist) + function Tapi_Impression(bufnum, arglist) if len(a:arglist) == 2 - echo "impression " . a:arglist[0] - echo "count " . a:arglist[1] + echomsg "impression " . a:arglist[0] + echomsg "count " . a:arglist[1] endif endfunc -< +< Output from `:echo` may be erased by a redraw, use `:echomsg` + to be able to see it with `:messages`. + drop {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: > exe "set t_ts=\<Esc>]51; t_fs=\x07" - let &titlestring = '["call","TryThis",["hello",123]]' + let &titlestring = '["call","Tapi_TryThis",["hello",123]]' redraw set t_ts& t_fs& diff --git a/src/terminal.c b/src/terminal.c index 50e87c9e4..5875af6e6 100644 --- a/src/terminal.c +++ b/src/terminal.c @@ -3193,7 +3193,7 @@ handle_call_command(term_T *term, channel_T *channel, listitem_T *item) } 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); return; diff --git a/src/testdir/test_terminal.vim b/src/testdir/test_terminal.vim index ff5056832..892da50d1 100644 --- a/src/testdir/test_terminal.vim +++ b/src/testdir/test_terminal.vim @@ -1072,24 +1072,28 @@ func Test_terminal_api_drop_oldwin() bwipe Xtextfile endfunc -func TryThis(bufnum, arg) +func Tapi_TryThis(bufnum, arg) let g:called_bufnum = a:bufnum let g:called_arg = a:arg endfunc -func Test_terminal_api_call() - if !CanRunVimInTerminal() - return - endif - +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","TryThis",["hello",123]]''', + \ 'let &titlestring = ''["call","' . a:funcname . '",["hello",123]]''', \ 'redraw', \ "set t_ts=", \ ], 'Xscript') +endfunc + +func Test_terminal_api_call() + if !CanRunVimInTerminal() + return + endif + + call WriteApiCall('Tapi_TryThis') let buf = RunVimInTerminal('-S Xscript', {}) call WaitFor({-> exists('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_arg 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 diff --git a/src/version.c b/src/version.c index 14bf136ad..df56277e7 100644 --- a/src/version.c +++ b/src/version.c @@ -767,6 +767,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1647, +/**/ 1646, /**/ 1645, |