comparison src/channel.c @ 28511:d7ca583e5772 v8.2.4780

patch 8.2.4780: parsing an LSP message fails when it is split Commit: https://github.com/vim/vim/commit/03cca297df5210f94be2246cfdb1ee9a30454bea Author: Yegappan Lakshmanan <yegappan@yahoo.com> Date: Mon Apr 18 14:07:46 2022 +0100 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)
author Bram Moolenaar <Bram@vim.org>
date Mon, 18 Apr 2022 15:15:04 +0200
parents 9f8563d05629
children 6b1da12297e5
comparison
equal deleted inserted replaced
28510:3f4bd5516667 28511:d7ca583e5772
2033 * When "want_nl" is TRUE collapse more buffers until a NL is found. 2033 * When "want_nl" is TRUE collapse more buffers until a NL is found.
2034 */ 2034 */
2035 int 2035 int
2036 channel_collapse(channel_T *channel, ch_part_T part, int want_nl) 2036 channel_collapse(channel_T *channel, ch_part_T part, int want_nl)
2037 { 2037 {
2038 readq_T *head = &channel->ch_part[part].ch_head; 2038 ch_mode_T mode = channel->ch_part[part].ch_mode;
2039 readq_T *node = head->rq_next; 2039 readq_T *head = &channel->ch_part[part].ch_head;
2040 readq_T *last_node; 2040 readq_T *node = head->rq_next;
2041 readq_T *n; 2041 readq_T *last_node;
2042 char_u *newbuf; 2042 readq_T *n;
2043 char_u *p; 2043 char_u *newbuf;
2044 long_u len; 2044 char_u *p;
2045 long_u len;
2045 2046
2046 if (node == NULL || node->rq_next == NULL) 2047 if (node == NULL || node->rq_next == NULL)
2047 return FAIL; 2048 return FAIL;
2048 2049
2049 last_node = node->rq_next; 2050 last_node = node->rq_next;
2050 len = node->rq_buflen + last_node->rq_buflen; 2051 len = node->rq_buflen + last_node->rq_buflen;
2051 if (want_nl) 2052 if (want_nl || mode == MODE_LSP)
2052 while (last_node->rq_next != NULL 2053 while (last_node->rq_next != NULL
2053 && channel_first_nl(last_node) == NULL) 2054 && (mode == MODE_LSP
2055 || channel_first_nl(last_node) == NULL))
2054 { 2056 {
2055 last_node = last_node->rq_next; 2057 last_node = last_node->rq_next;
2056 len += last_node->rq_buflen; 2058 len += last_node->rq_buflen;
2057 } 2059 }
2058 2060
3004 int argc = 0; 3006 int argc = 0;
3005 3007
3006 // Get any json message in the queue. 3008 // Get any json message in the queue.
3007 if (channel_get_json(channel, part, -1, FALSE, &listtv) == FAIL) 3009 if (channel_get_json(channel, part, -1, FALSE, &listtv) == FAIL)
3008 { 3010 {
3011 if (ch_mode == MODE_LSP)
3012 // In the "lsp" mode, the http header and the json payload may
3013 // be received in multiple messages. So concatenate all the
3014 // received messages.
3015 (void)channel_collapse(channel, part, FALSE);
3016
3009 // Parse readahead, return when there is still no message. 3017 // Parse readahead, return when there is still no message.
3010 channel_parse_json(channel, part); 3018 channel_parse_json(channel, part);
3011 if (channel_get_json(channel, part, -1, FALSE, &listtv) == FAIL) 3019 if (channel_get_json(channel, part, -1, FALSE, &listtv) == FAIL)
3012 return FALSE; 3020 return FALSE;
3013 } 3021 }
3972 { 3980 {
3973 int more; 3981 int more;
3974 sock_T fd; 3982 sock_T fd;
3975 int timeout; 3983 int timeout;
3976 chanpart_T *chanpart = &channel->ch_part[part]; 3984 chanpart_T *chanpart = &channel->ch_part[part];
3985 ch_mode_T mode = channel->ch_part[part].ch_mode;
3977 int retval = FAIL; 3986 int retval = FAIL;
3978 3987
3979 ch_log(channel, "Blocking read JSON for id %d", id); 3988 ch_log(channel, "Blocking read JSON for id %d", id);
3980 ++channel_blocking_wait; 3989 ++channel_blocking_wait;
3981 3990
3982 if (id >= 0) 3991 if (id >= 0)
3983 channel_add_block_id(chanpart, id); 3992 channel_add_block_id(chanpart, id);
3984 3993
3985 for (;;) 3994 for (;;)
3986 { 3995 {
3996 if (mode == MODE_LSP)
3997 // In the "lsp" mode, the http header and the json payload may be
3998 // received in multiple messages. So concatenate all the received
3999 // messages.
4000 (void)channel_collapse(channel, part, FALSE);
4001
3987 more = channel_parse_json(channel, part); 4002 more = channel_parse_json(channel, part);
3988 4003
3989 // search for message "id" 4004 // search for message "id"
3990 if (channel_get_json(channel, part, id, TRUE, rettv) == OK) 4005 if (channel_get_json(channel, part, id, TRUE, rettv) == OK)
3991 { 4006 {