changeset 7916:54602dcac207 v7.4.1254

commit https://github.com/vim/vim/commit/3b05b135e3ee4cfd59983fd63461e8f7642c1713 Author: Bram Moolenaar <Bram@vim.org> Date: Wed Feb 3 23:25:07 2016 +0100 patch 7.4.1254 Problem: Opening a second channel causes a crash. (Ken Takata) Solution: Don't re-allocate the array with channels.
author Christian Brabandt <cb@256bit.org>
date Wed, 03 Feb 2016 23:30:04 +0100
parents 72085904c404
children 23397b25221e
files src/channel.c src/testdir/test_channel.py src/testdir/test_channel.vim src/version.c
diffstat 4 files changed, 40 insertions(+), 21 deletions(-) [+]
line wrap: on
line diff
--- a/src/channel.c
+++ b/src/channel.c
@@ -133,22 +133,25 @@ FILE *debugfd = NULL;
 add_channel(void)
 {
     int		idx;
-    channel_T	*new_channels;
     channel_T	*ch;
 
     if (channels != NULL)
+    {
 	for (idx = 0; idx < channel_count; ++idx)
 	    if (channels[idx].ch_fd < 0)
 		/* re-use a closed channel slot */
 		return idx;
-    if (channel_count == MAX_OPEN_CHANNELS)
-	return -1;
-    new_channels = (channel_T *)alloc(sizeof(channel_T) * (channel_count + 1));
-    if (new_channels == NULL)
-	return -1;
-    if (channels != NULL)
-	mch_memmove(new_channels, channels, sizeof(channel_T) * channel_count);
-    channels = new_channels;
+	if (channel_count == MAX_OPEN_CHANNELS)
+	    return -1;
+    }
+    else
+    {
+	channels = (channel_T *)alloc((int)sizeof(channel_T)
+							 * MAX_OPEN_CHANNELS);
+	if (channels == NULL)
+	    return -1;
+    }
+
     ch = &channels[channel_count];
     (void)vim_memset(ch, 0, sizeof(channel_T));
 
--- a/src/testdir/test_channel.py
+++ b/src/testdir/test_channel.py
@@ -24,14 +24,10 @@ except ImportError:
     # Python 2
     import SocketServer as socketserver
 
-thesocket = None
-
 class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler):
 
     def handle(self):
         print("=== socket opened ===")
-        global thesocket
-        thesocket = self.request
         while True:
             try:
                 received = self.request.recv(4096).decode('utf-8')
@@ -77,19 +73,19 @@ class ThreadedTCPRequestHandler(socketse
                         cmd = '["ex","call append(\\"$\\",\\"added1\\")"]'
                         cmd += '["ex","call append(\\"$\\",\\"added2\\")"]'
                         print("sending: {}".format(cmd))
-                        thesocket.sendall(cmd.encode('utf-8'))
+                        self.request.sendall(cmd.encode('utf-8'))
                         response = "ok"
                     elif decoded[1] == 'eval-works':
                         # Send an eval request.  We ignore the response.
                         cmd = '["eval","\\"foo\\" . 123", -1]'
                         print("sending: {}".format(cmd))
-                        thesocket.sendall(cmd.encode('utf-8'))
+                        self.request.sendall(cmd.encode('utf-8'))
                         response = "ok"
                     elif decoded[1] == 'eval-fails':
                         # Send an eval request that will fail.
                         cmd = '["eval","xxx", -2]'
                         print("sending: {}".format(cmd))
-                        thesocket.sendall(cmd.encode('utf-8'))
+                        self.request.sendall(cmd.encode('utf-8'))
                         response = "ok"
                     elif decoded[1] == 'eval-result':
                         # Send back the last received eval result.
@@ -105,14 +101,12 @@ class ThreadedTCPRequestHandler(socketse
 
                     encoded = json.dumps([decoded[0], response])
                     print("sending: {}".format(encoded))
-                    thesocket.sendall(encoded.encode('utf-8'))
+                    self.request.sendall(encoded.encode('utf-8'))
 
                 # Negative numbers are used for "eval" responses.
                 elif decoded[0] < 0:
                     last_eval = decoded
 
-        thesocket = None
-
 class ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
     pass
 
--- a/src/testdir/test_channel.vim
+++ b/src/testdir/test_channel.vim
@@ -17,6 +17,8 @@ else
   finish
 endif
 
+let s:port = -1
+
 func s:start_server()
   " The Python program writes the port number in Xportnr.
   call delete("Xportnr")
@@ -49,9 +51,9 @@ func s:start_server()
     call assert_false(1, "Can't start test_channel.py")
     return -1
   endif
-  let port = l[0]
+  let s:port = l[0]
 
-  let handle = ch_open('localhost:' . port, 'json')
+  let handle = ch_open('localhost:' . s:port, 'json')
   return handle
 endfunc
 
@@ -94,6 +96,24 @@ func Test_communicate()
   call s:kill_server()
 endfunc
 
+" Test that we can open two channels.
+func Test_two_channels()
+  let handle = s:start_server()
+  if handle < 0
+    return
+  endif
+  call assert_equal('got it', ch_sendexpr(handle, 'hello!'))
+
+  let newhandle = ch_open('localhost:' . s:port, 'json')
+  call assert_equal('got it', ch_sendexpr(newhandle, 'hello!'))
+  call assert_equal('got it', ch_sendexpr(handle, 'hello!'))
+
+  call ch_close(handle)
+  call assert_equal('got it', ch_sendexpr(newhandle, 'hello!'))
+
+  call s:kill_server()
+endfunc
+
 " Test that a server crash is handled gracefully.
 func Test_server_crash()
   let handle = s:start_server()
--- a/src/version.c
+++ b/src/version.c
@@ -743,6 +743,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    1254,
+/**/
     1253,
 /**/
     1252,