]> granicus.if.org Git - vim/commitdiff
patch 8.0.0596: crash when complete() called after complete_add() v8.0.0596
authorBram Moolenaar <Bram@vim.org>
Mon, 1 May 2017 18:46:52 +0000 (20:46 +0200)
committerBram Moolenaar <Bram@vim.org>
Mon, 1 May 2017 18:46:52 +0000 (20:46 +0200)
Problem:    Crash when complete() is called after complete_add() in
            'completefunc'. (Lifepillar)
Solution:   Bail out if compl_pattern is NULL. (closes #1668)
            Also avoid using freed memory.

src/edit.c
src/testdir/test_popup.vim
src/version.c

index 0153f3b9d5d01edd0624f0640416e97b6b716138..89a5fae072f1355230a0110a39d8e23c63e67aef 100644 (file)
@@ -96,6 +96,7 @@ struct compl_S
 static compl_T    *compl_first_match = NULL;
 static compl_T    *compl_curr_match = NULL;
 static compl_T    *compl_shown_match = NULL;
+static compl_T    *compl_old_match = NULL;
 
 /* After using a cursor key <Enter> selects a match in the popup menu,
  * otherwise it inserts a line break. */
@@ -3431,6 +3432,7 @@ ins_compl_free(void)
     } while (compl_curr_match != NULL && compl_curr_match != compl_first_match);
     compl_first_match = compl_curr_match = NULL;
     compl_shown_match = NULL;
+    compl_old_match = NULL;
 }
 
     static void
@@ -4272,7 +4274,6 @@ ins_compl_get_exp(pos_T *ini)
     char_u     *ptr;
     char_u     *dict = NULL;
     int                dict_f = 0;
-    compl_T    *old_match;
     int                set_match_pos;
 
     if (!compl_started)
@@ -4286,7 +4287,7 @@ ins_compl_get_exp(pos_T *ini)
        last_match_pos = first_match_pos = *ini;
     }
 
-    old_match = compl_curr_match;      /* remember the last current match */
+    compl_old_match = compl_curr_match;        /* remember the last current match */
     pos = (compl_direction == FORWARD) ? &last_match_pos : &first_match_pos;
     /* For ^N/^P loop over all the flags/windows/buffers in 'complete' */
     for (;;)
@@ -4388,6 +4389,11 @@ ins_compl_get_exp(pos_T *ini)
            }
        }
 
+       /* If complete() was called then compl_pattern has been reset.  The
+        * following won't work then, bail out. */
+       if (compl_pattern == NULL)
+           break;
+
        switch (type)
        {
        case -1:
@@ -4621,7 +4627,7 @@ ins_compl_get_exp(pos_T *ini)
 
        /* check if compl_curr_match has changed, (e.g. other type of
         * expansion added something) */
-       if (type != 0 && compl_curr_match != old_match)
+       if (type != 0 && compl_curr_match != compl_old_match)
            found_new_match = OK;
 
        /* break the loop for specialized modes (use 'complete' just for the
@@ -4660,13 +4666,16 @@ ins_compl_get_exp(pos_T *ini)
            || (ctrl_x_mode != 0 && !CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode)))
        i = ins_compl_make_cyclic();
 
-    /* If several matches were added (FORWARD) or the search failed and has
-     * just been made cyclic then we have to move compl_curr_match to the next
-     * or previous entry (if any) -- Acevedo */
-    compl_curr_match = compl_direction == FORWARD ? old_match->cp_next
-                                                        : old_match->cp_prev;
-    if (compl_curr_match == NULL)
-       compl_curr_match = old_match;
+    if (compl_old_match != NULL)
+    {
+       /* If several matches were added (FORWARD) or the search failed and has
+        * just been made cyclic then we have to move compl_curr_match to the
+        * next or previous entry (if any) -- Acevedo */
+       compl_curr_match = compl_direction == FORWARD ? compl_old_match->cp_next
+                                                   : compl_old_match->cp_prev;
+       if (compl_curr_match == NULL)
+           compl_curr_match = compl_old_match;
+    }
     return i;
 }
 
index 4789ca76b21fce9d215b5cac2dde447e3d16c2f6..25d766f7b9d037dfb0d54ac77a7cc366467999ab 100644 (file)
@@ -570,4 +570,47 @@ func Test_completion_comment_formatting()
   bwipe!
 endfunc
 
+fun MessCompleteMonths()
+  for m in split("Jan Feb Mar Apr May Jun Jul Aug Sep")
+    call complete_add(m)
+    if complete_check()
+      break
+    endif
+  endfor
+  return []
+endfun
+
+fun MessCompleteMore()
+  call complete(1, split("Oct Nov Dec"))
+  return []
+endfun
+
+fun MessComplete(findstart, base)
+  if a:findstart
+    let line = getline('.')
+    let start = col('.') - 1
+    while start > 0 && line[start - 1] =~ '\a'
+      let start -= 1
+    endwhile
+    return start
+  else
+    call MessCompleteMonths()
+    call MessCompleteMore()
+    return []
+  endif
+endf
+
+func Test_complete_func_mess()
+  " Calling complete() after complete_add() in 'completefunc' is wrong, but it
+  " should not crash.
+  set completefunc=MessComplete
+  new
+  call setline(1, 'Ju')
+  call feedkeys("A\<c-x>\<c-u>/\<esc>", 'tx')
+  call assert_equal('Oct/Oct', getline(1))
+  bwipe!
+  set completefunc=
+endfunc
+
+
 " vim: shiftwidth=2 sts=2 expandtab
index 8895b73b0f3ace4935903706f6555d2dfd5e294e..f31a946dc073c2d33666927b1892c3f6aa8006b7 100644 (file)
@@ -764,6 +764,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    596,
 /**/
     595,
 /**/