diff options
author | Yegappan Lakshmanan <yegappan@yahoo.com> | 2022-04-18 14:07:46 +0100 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2022-04-18 14:07:46 +0100 |
commit | 03cca297df5210f94be2246cfdb1ee9a30454bea (patch) | |
tree | cc2f525d9f41ad11e2d0520c0c7b0d8d557455f8 /src/channel.c | |
parent | 53e8f3ffdf80dbd24a60adb51f8f21982fd41c57 (diff) |
patch 8.2.4780: parsing an LSP message fails when it is splitv8.2.4780
Problem: Parsing an LSP message fails when it is split.
Solution: Collapse the received data before parsing. (Yegappan Lakshmanan,
closes #10215)
Diffstat (limited to 'src/channel.c')
-rw-r--r-- | src/channel.c | 33 |
1 files changed, 24 insertions, 9 deletions
diff --git a/src/channel.c b/src/channel.c index 79f4dbc29b..b981af4006 100644 --- a/src/channel.c +++ b/src/channel.c @@ -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" |