forked from aniani/vim
patch 7.4.1254
Problem: Opening a second channel causes a crash. (Ken Takata) Solution: Don't re-allocate the array with channels.
This commit is contained in:
@@ -133,22 +133,25 @@ FILE *debugfd = NULL;
|
|||||||
add_channel(void)
|
add_channel(void)
|
||||||
{
|
{
|
||||||
int idx;
|
int idx;
|
||||||
channel_T *new_channels;
|
|
||||||
channel_T *ch;
|
channel_T *ch;
|
||||||
|
|
||||||
if (channels != NULL)
|
if (channels != NULL)
|
||||||
|
{
|
||||||
for (idx = 0; idx < channel_count; ++idx)
|
for (idx = 0; idx < channel_count; ++idx)
|
||||||
if (channels[idx].ch_fd < 0)
|
if (channels[idx].ch_fd < 0)
|
||||||
/* re-use a closed channel slot */
|
/* re-use a closed channel slot */
|
||||||
return idx;
|
return idx;
|
||||||
if (channel_count == MAX_OPEN_CHANNELS)
|
if (channel_count == MAX_OPEN_CHANNELS)
|
||||||
return -1;
|
return -1;
|
||||||
new_channels = (channel_T *)alloc(sizeof(channel_T) * (channel_count + 1));
|
}
|
||||||
if (new_channels == NULL)
|
else
|
||||||
return -1;
|
{
|
||||||
if (channels != NULL)
|
channels = (channel_T *)alloc((int)sizeof(channel_T)
|
||||||
mch_memmove(new_channels, channels, sizeof(channel_T) * channel_count);
|
* MAX_OPEN_CHANNELS);
|
||||||
channels = new_channels;
|
if (channels == NULL)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
ch = &channels[channel_count];
|
ch = &channels[channel_count];
|
||||||
(void)vim_memset(ch, 0, sizeof(channel_T));
|
(void)vim_memset(ch, 0, sizeof(channel_T));
|
||||||
|
|
||||||
|
@@ -24,14 +24,10 @@ except ImportError:
|
|||||||
# Python 2
|
# Python 2
|
||||||
import SocketServer as socketserver
|
import SocketServer as socketserver
|
||||||
|
|
||||||
thesocket = None
|
|
||||||
|
|
||||||
class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler):
|
class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler):
|
||||||
|
|
||||||
def handle(self):
|
def handle(self):
|
||||||
print("=== socket opened ===")
|
print("=== socket opened ===")
|
||||||
global thesocket
|
|
||||||
thesocket = self.request
|
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
received = self.request.recv(4096).decode('utf-8')
|
received = self.request.recv(4096).decode('utf-8')
|
||||||
@@ -77,19 +73,19 @@ class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler):
|
|||||||
cmd = '["ex","call append(\\"$\\",\\"added1\\")"]'
|
cmd = '["ex","call append(\\"$\\",\\"added1\\")"]'
|
||||||
cmd += '["ex","call append(\\"$\\",\\"added2\\")"]'
|
cmd += '["ex","call append(\\"$\\",\\"added2\\")"]'
|
||||||
print("sending: {}".format(cmd))
|
print("sending: {}".format(cmd))
|
||||||
thesocket.sendall(cmd.encode('utf-8'))
|
self.request.sendall(cmd.encode('utf-8'))
|
||||||
response = "ok"
|
response = "ok"
|
||||||
elif decoded[1] == 'eval-works':
|
elif decoded[1] == 'eval-works':
|
||||||
# Send an eval request. We ignore the response.
|
# Send an eval request. We ignore the response.
|
||||||
cmd = '["eval","\\"foo\\" . 123", -1]'
|
cmd = '["eval","\\"foo\\" . 123", -1]'
|
||||||
print("sending: {}".format(cmd))
|
print("sending: {}".format(cmd))
|
||||||
thesocket.sendall(cmd.encode('utf-8'))
|
self.request.sendall(cmd.encode('utf-8'))
|
||||||
response = "ok"
|
response = "ok"
|
||||||
elif decoded[1] == 'eval-fails':
|
elif decoded[1] == 'eval-fails':
|
||||||
# Send an eval request that will fail.
|
# Send an eval request that will fail.
|
||||||
cmd = '["eval","xxx", -2]'
|
cmd = '["eval","xxx", -2]'
|
||||||
print("sending: {}".format(cmd))
|
print("sending: {}".format(cmd))
|
||||||
thesocket.sendall(cmd.encode('utf-8'))
|
self.request.sendall(cmd.encode('utf-8'))
|
||||||
response = "ok"
|
response = "ok"
|
||||||
elif decoded[1] == 'eval-result':
|
elif decoded[1] == 'eval-result':
|
||||||
# Send back the last received eval result.
|
# Send back the last received eval result.
|
||||||
@@ -105,14 +101,12 @@ class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler):
|
|||||||
|
|
||||||
encoded = json.dumps([decoded[0], response])
|
encoded = json.dumps([decoded[0], response])
|
||||||
print("sending: {}".format(encoded))
|
print("sending: {}".format(encoded))
|
||||||
thesocket.sendall(encoded.encode('utf-8'))
|
self.request.sendall(encoded.encode('utf-8'))
|
||||||
|
|
||||||
# Negative numbers are used for "eval" responses.
|
# Negative numbers are used for "eval" responses.
|
||||||
elif decoded[0] < 0:
|
elif decoded[0] < 0:
|
||||||
last_eval = decoded
|
last_eval = decoded
|
||||||
|
|
||||||
thesocket = None
|
|
||||||
|
|
||||||
class ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
|
class ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@@ -17,6 +17,8 @@ else
|
|||||||
finish
|
finish
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
let s:port = -1
|
||||||
|
|
||||||
func s:start_server()
|
func s:start_server()
|
||||||
" The Python program writes the port number in Xportnr.
|
" The Python program writes the port number in Xportnr.
|
||||||
call delete("Xportnr")
|
call delete("Xportnr")
|
||||||
@@ -49,9 +51,9 @@ func s:start_server()
|
|||||||
call assert_false(1, "Can't start test_channel.py")
|
call assert_false(1, "Can't start test_channel.py")
|
||||||
return -1
|
return -1
|
||||||
endif
|
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
|
return handle
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
@@ -94,6 +96,24 @@ func Test_communicate()
|
|||||||
call s:kill_server()
|
call s:kill_server()
|
||||||
endfunc
|
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.
|
" Test that a server crash is handled gracefully.
|
||||||
func Test_server_crash()
|
func Test_server_crash()
|
||||||
let handle = s:start_server()
|
let handle = s:start_server()
|
||||||
|
@@ -742,6 +742,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 */
|
||||||
|
/**/
|
||||||
|
1254,
|
||||||
/**/
|
/**/
|
||||||
1253,
|
1253,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user