diff options
author | Bram Moolenaar <Bram@vim.org> | 2022-04-26 18:52:22 +0100 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2022-04-26 18:52:22 +0100 |
commit | 23f106efeb64eadd95adee34144f64526aa5f61f (patch) | |
tree | 1459ea8eabf4985809bfc8700a92f3e6b1cf2c22 | |
parent | 17c95d9608370559441bb73941ba6d9a4b6b26bd (diff) |
patch 8.2.4830: possible endless loop if there is unused typaheadv8.2.4830
Problem: Possible endless loop if there is unused typahead.
Solution: Only loop when the typeahead changed.
-rw-r--r-- | src/channel.c | 48 | ||||
-rw-r--r-- | src/version.c | 2 |
2 files changed, 38 insertions, 12 deletions
diff --git a/src/channel.c b/src/channel.c index 87dc00cd0c..d6782e9182 100644 --- a/src/channel.c +++ b/src/channel.c @@ -2029,7 +2029,7 @@ channel_consume(channel_T *channel, ch_part_T part, int len) /* * Collapses the first and second buffer for "channel"/"part". - * Returns FAIL if that is not possible. + * Returns FAIL if nothing was done. * When "want_nl" is TRUE collapse more buffers until a NL is found. * When the channel part mode is "lsp", collapse all the buffers as the http * header and the JSON content can be present in multiple buffers. @@ -2957,6 +2957,17 @@ drop_messages(channel_T *channel, ch_part_T part) } /* + * Return TRUE if for "channel" / "part" ch_json_head should be used. + */ + static int +channel_use_json_head(channel_T *channel, ch_part_T part) +{ + ch_mode_T ch_mode = channel->ch_part[part].ch_mode; + + return ch_mode == MODE_JSON || ch_mode == MODE_JS || ch_mode == MODE_LSP; +} + +/* * Invoke a callback for "channel"/"part" if needed. * This does not redraw but sets channel_need_redraw when redraw is needed. * Return TRUE when a message was handled, there might be another one. @@ -3002,7 +3013,7 @@ may_invoke_callback(channel_T *channel, ch_part_T part) buffer = NULL; } - if (ch_mode == MODE_JSON || ch_mode == MODE_JS || ch_mode == MODE_LSP) + if (channel_use_json_head(channel, part)) { listitem_T *item; int argc = 0; @@ -3248,14 +3259,13 @@ channel_is_open(channel_T *channel) } /* - * Return TRUE if "channel" has JSON or other typeahead. + * Return a pointer indicating the readahead. Can only be compared between + * calls. Returns NULL if there is no readahead. */ - static int -channel_has_readahead(channel_T *channel, ch_part_T part) + static void * +channel_readahead_pointer(channel_T *channel, ch_part_T part) { - ch_mode_T ch_mode = channel->ch_part[part].ch_mode; - - if (ch_mode == MODE_JSON || ch_mode == MODE_JS || ch_mode == MODE_LSP) + if (channel_use_json_head(channel, part)) { jsonq_T *head = &channel->ch_part[part].ch_json_head; @@ -3264,9 +3274,18 @@ channel_has_readahead(channel_T *channel, ch_part_T part) // process. channel_parse_json(channel, part); - return head->jq_next != NULL; + return head->jq_next; } - return channel_peek(channel, part) != NULL; + return channel_peek(channel, part); +} + +/* + * Return TRUE if "channel" has JSON or other typeahead. + */ + static int +channel_has_readahead(channel_T *channel, ch_part_T part) +{ + return channel_readahead_pointer(channel, part) != NULL; } /* @@ -4013,14 +4032,19 @@ channel_read_json_block( if (!more) { + void *prev_readahead_ptr = channel_readahead_pointer(channel, part); + void *readahead_ptr; + // Handle any other messages in the queue. If done some more // messages may have arrived. if (channel_parse_messages()) continue; // channel_parse_messages() may fill the queue with new data to - // process. - if (channel_has_readahead(channel, part)) + // process. Only loop when the readahead changed, otherwise we + // would busy-loop. + readahead_ptr = channel_readahead_pointer(channel, part); + if (readahead_ptr != NULL && readahead_ptr != prev_readahead_ptr) continue; // Wait for up to the timeout. If there was an incomplete message diff --git a/src/version.c b/src/version.c index 54f350bf87..1c799d89e5 100644 --- a/src/version.c +++ b/src/version.c @@ -747,6 +747,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 4830, +/**/ 4829, /**/ 4828, |