summaryrefslogtreecommitdiffstats
path: root/src/insexpand.c
diff options
context:
space:
mode:
authorAndy Gozas <andy@gozas.me>2021-08-05 16:23:27 +0200
committerBram Moolenaar <Bram@vim.org>2021-08-05 16:23:27 +0200
commit6a230c6b32695393785ae64b440ce5f023a22382 (patch)
treed4fe55c5a64ae1024bfd1f8ef6a41663879cabf6 /src/insexpand.c
parentbc67e5a0a494f5fc48e872d747371e31a782d171 (diff)
patch 8.2.3293: finding completions may cause an endless loopv8.2.3293
Problem: Finding completions may cause an endless loop. Solution: Use a better way to check coming back where the search started. (Andy Gozas, closes #8672, closes #8671)
Diffstat (limited to 'src/insexpand.c')
-rw-r--r--src/insexpand.c28
1 files changed, 27 insertions, 1 deletions
diff --git a/src/insexpand.c b/src/insexpand.c
index 3b58891fcc..4f8a626517 100644
--- a/src/insexpand.c
+++ b/src/insexpand.c
@@ -2712,6 +2712,8 @@ ins_compl_get_exp(pos_T *ini)
char_u *dict = NULL;
int dict_f = 0;
int set_match_pos;
+ pos_T prev_pos = {0, 0, 0};
+ int looped_around = FALSE;
if (!compl_started)
{
@@ -2964,6 +2966,7 @@ ins_compl_get_exp(pos_T *ini)
p_ws = FALSE;
else if (*e_cpt == '.')
p_ws = TRUE;
+ looped_around = FALSE;
for (;;)
{
int cont_s_ipos = FALSE;
@@ -2991,8 +2994,31 @@ ins_compl_get_exp(pos_T *ini)
set_match_pos = FALSE;
}
else if (first_match_pos.lnum == last_match_pos.lnum
- && first_match_pos.col == last_match_pos.col)
+ && first_match_pos.col == last_match_pos.col)
+ {
found_new_match = FAIL;
+ }
+ else if ((compl_direction == FORWARD)
+ && (prev_pos.lnum > pos->lnum
+ || (prev_pos.lnum == pos->lnum
+ && prev_pos.col >= pos->col)))
+ {
+ if (looped_around)
+ found_new_match = FAIL;
+ else
+ looped_around = TRUE;
+ }
+ else if ((compl_direction != FORWARD)
+ && (prev_pos.lnum < pos->lnum
+ || (prev_pos.lnum == pos->lnum
+ && prev_pos.col <= pos->col)))
+ {
+ if (looped_around)
+ found_new_match = FAIL;
+ else
+ looped_around = TRUE;
+ }
+ prev_pos = *pos;
if (found_new_match == FAIL)
{
if (ins_buf == curbuf)