forked from aniani/vim
patch 8.2.4780: parsing an LSP message fails when it is split
Problem: Parsing an LSP message fails when it is split. Solution: Collapse the received data before parsing. (Yegappan Lakshmanan, closes #10215)
This commit is contained in:
committed by
Bram Moolenaar
parent
53e8f3ffdf
commit
03cca297df
@@ -2035,22 +2035,24 @@ channel_consume(channel_T *channel, ch_part_T part, int len)
|
||||
int
|
||||
channel_collapse(channel_T *channel, ch_part_T part, int want_nl)
|
||||
{
|
||||
readq_T *head = &channel->ch_part[part].ch_head;
|
||||
readq_T *node = head->rq_next;
|
||||
readq_T *last_node;
|
||||
readq_T *n;
|
||||
char_u *newbuf;
|
||||
char_u *p;
|
||||
long_u len;
|
||||
ch_mode_T mode = channel->ch_part[part].ch_mode;
|
||||
readq_T *head = &channel->ch_part[part].ch_head;
|
||||
readq_T *node = head->rq_next;
|
||||
readq_T *last_node;
|
||||
readq_T *n;
|
||||
char_u *newbuf;
|
||||
char_u *p;
|
||||
long_u len;
|
||||
|
||||
if (node == NULL || node->rq_next == NULL)
|
||||
return FAIL;
|
||||
|
||||
last_node = node->rq_next;
|
||||
len = node->rq_buflen + last_node->rq_buflen;
|
||||
if (want_nl)
|
||||
if (want_nl || mode == MODE_LSP)
|
||||
while (last_node->rq_next != NULL
|
||||
&& channel_first_nl(last_node) == NULL)
|
||||
&& (mode == MODE_LSP
|
||||
|| channel_first_nl(last_node) == NULL))
|
||||
{
|
||||
last_node = last_node->rq_next;
|
||||
len += last_node->rq_buflen;
|
||||
@@ -3006,6 +3008,12 @@ may_invoke_callback(channel_T *channel, ch_part_T part)
|
||||
// Get any json message in the queue.
|
||||
if (channel_get_json(channel, part, -1, FALSE, &listtv) == FAIL)
|
||||
{
|
||||
if (ch_mode == MODE_LSP)
|
||||
// In the "lsp" mode, the http header and the json payload may
|
||||
// be received in multiple messages. So concatenate all the
|
||||
// received messages.
|
||||
(void)channel_collapse(channel, part, FALSE);
|
||||
|
||||
// Parse readahead, return when there is still no message.
|
||||
channel_parse_json(channel, part);
|
||||
if (channel_get_json(channel, part, -1, FALSE, &listtv) == FAIL)
|
||||
@@ -3974,6 +3982,7 @@ channel_read_json_block(
|
||||
sock_T fd;
|
||||
int timeout;
|
||||
chanpart_T *chanpart = &channel->ch_part[part];
|
||||
ch_mode_T mode = channel->ch_part[part].ch_mode;
|
||||
int retval = FAIL;
|
||||
|
||||
ch_log(channel, "Blocking read JSON for id %d", id);
|
||||
@@ -3984,6 +3993,12 @@ channel_read_json_block(
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (mode == MODE_LSP)
|
||||
// In the "lsp" mode, the http header and the json payload may be
|
||||
// received in multiple messages. So concatenate all the received
|
||||
// messages.
|
||||
(void)channel_collapse(channel, part, FALSE);
|
||||
|
||||
more = channel_parse_json(channel, part);
|
||||
|
||||
// search for message "id"
|
||||
|
Reference in New Issue
Block a user