summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2016-03-20 14:31:00 +0100
committerBram Moolenaar <Bram@vim.org>2016-03-20 14:31:00 +0100
commitac74d5e86cd16b42e81ba48f58f3d45c72758248 (patch)
tree54b1ebc8573e8e4d0f09215ccc829df310b07431
parent829c8e369630a7cbbdac015d8177b7fde25e2f19 (diff)
downloadvim-git-ac74d5e86cd16b42e81ba48f58f3d45c72758248.tar.gz
patch 7.4.1616v7.4.1616
Problem: Malformed channel request causes a hang. Solution: Drop malformed message. (Damien)
-rw-r--r--src/channel.c33
-rw-r--r--src/testdir/test_channel.py5
-rw-r--r--src/testdir/test_channel.vim4
-rw-r--r--src/version.c2
4 files changed, 34 insertions, 10 deletions
diff --git a/src/channel.c b/src/channel.c
index 2a71077fd..0d3f452d5 100644
--- a/src/channel.c
+++ b/src/channel.c
@@ -1481,9 +1481,17 @@ channel_parse_json(channel_T *channel, int part)
* TODO: insert in front */
if (reader.js_buf[reader.js_used] != NUL)
{
- channel_save(channel, part, reader.js_buf + reader.js_used,
- (int)(reader.js_end - reader.js_buf) - reader.js_used);
- ret = TRUE;
+ if (ret == FAIL)
+ {
+ ch_error(channel, "Decoding failed - discarding input");
+ ret = FALSE;
+ }
+ else
+ {
+ channel_save(channel, part, reader.js_buf + reader.js_used,
+ (int)(reader.js_end - reader.js_buf) - reader.js_used);
+ ret = TRUE;
+ }
}
else
ret = FALSE;
@@ -1586,12 +1594,14 @@ channel_exe_cmd(channel_T *channel, int part, typval_T *argv)
if (STRCMP(cmd, "ex") == 0)
{
+ ch_logs(channel, "Executing ex command '%s'", (char *)arg);
do_cmdline_cmd(arg);
}
else if (STRCMP(cmd, "normal") == 0)
{
exarg_T ea;
+ ch_logs(channel, "Executing normal command '%s'", (char *)arg);
ea.arg = arg;
ea.addr_count = 0;
ea.forceit = TRUE; /* no mapping */
@@ -1601,6 +1611,7 @@ channel_exe_cmd(channel_T *channel, int part, typval_T *argv)
{
exarg_T ea;
+ ch_log(channel, "redraw");
ea.forceit = *arg != NUL;
ex_redraw(&ea);
showruler(FALSE);
@@ -1642,11 +1653,18 @@ channel_exe_cmd(channel_T *channel, int part, typval_T *argv)
/* Don't pollute the display with errors. */
++emsg_skip;
if (!is_call)
+ {
+ ch_logs(channel, "Evaluating expression '%s'", (char *)arg);
tv = eval_expr(arg, NULL);
- else if (func_call(arg, &argv[2], NULL, NULL, &res_tv) == OK)
- tv = &res_tv;
+ }
else
- tv = NULL;
+ {
+ ch_logs(channel, "Calling '%s'", (char *)arg);
+ if (func_call(arg, &argv[2], NULL, NULL, &res_tv) == OK)
+ tv = &res_tv;
+ else
+ tv = NULL;
+ }
if (argv[id_idx].v_type == VAR_NUMBER)
{
@@ -1848,10 +1866,7 @@ may_invoke_callback(channel_T *channel, int part)
if (argv[0].v_type == VAR_STRING)
{
- char_u *cmd = argv[0].vval.v_string;
-
/* ["cmd", arg] or ["cmd", arg, arg] or ["cmd", arg, arg, arg] */
- ch_logs(channel, "Executing %s command", (char *)cmd);
channel_exe_cmd(channel, part, argv);
free_tv(listtv);
return TRUE;
diff --git a/src/testdir/test_channel.py b/src/testdir/test_channel.py
index a465d65d2..47a12ea7e 100644
--- a/src/testdir/test_channel.py
+++ b/src/testdir/test_channel.py
@@ -104,6 +104,11 @@ class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler):
print("sending: {}".format(cmd))
self.request.sendall(cmd.encode('utf-8'))
response = "ok"
+ elif decoded[1] == 'malformed':
+ cmd = '["ex",":"]wrong!["ex","smi"]'
+ print("sending: {}".format(cmd))
+ self.request.sendall(cmd.encode('utf-8'))
+ response = "ok"
elif decoded[1] == 'an expr':
# Send an expr request.
cmd = '["expr","setline(\\"$\\", [\\"one\\",\\"two\\",\\"three\\"])"]'
diff --git a/src/testdir/test_channel.vim b/src/testdir/test_channel.vim
index 6d38bffce..c628bbe88 100644
--- a/src/testdir/test_channel.vim
+++ b/src/testdir/test_channel.vim
@@ -123,10 +123,12 @@ func s:communicate(port)
" check that no job is handled correctly
call assert_equal('no process', string(ch_getjob(handle)))
endif
-
" Simple string request and reply.
call assert_equal('got it', ch_evalexpr(handle, 'hello!'))
+ " Malformed command should be ignored.
+ call assert_equal('ok', ch_evalexpr(handle, 'malformed'))
+
" Request that triggers sending two ex commands. These will usually be
" handled before getting the response, but it's not guaranteed, thus wait a
" tiny bit for the commands to get executed.
diff --git a/src/version.c b/src/version.c
index 2dbc1764c..c914ec479 100644
--- a/src/version.c
+++ b/src/version.c
@@ -749,6 +749,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 1616,
+/**/
1615,
/**/
1614,