To: vim_dev@googlegroups.com Subject: Patch 8.0.0596 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.0.0596 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. Files: src/edit.c, src/testdir/test_popup.vim *** ../vim-8.0.0595/src/edit.c 2017-04-07 14:01:54.844119764 +0200 --- src/edit.c 2017-05-01 20:38:34.690463875 +0200 *************** *** 96,101 **** --- 96,102 ---- 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 selects a match in the popup menu, * otherwise it inserts a line break. */ *************** *** 3431,3436 **** --- 3432,3438 ---- } 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,4278 **** char_u *ptr; char_u *dict = NULL; int dict_f = 0; - compl_T *old_match; int set_match_pos; if (!compl_started) --- 4274,4279 ---- *************** *** 4286,4292 **** last_match_pos = first_match_pos = *ini; } ! 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 (;;) --- 4287,4293 ---- last_match_pos = first_match_pos = *ini; } ! 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,4393 **** --- 4389,4399 ---- } } + /* 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,4627 **** /* check if compl_curr_match has changed, (e.g. other type of * expansion added something) */ ! if (type != 0 && compl_curr_match != old_match) found_new_match = OK; /* break the loop for specialized modes (use 'complete' just for the --- 4627,4633 ---- /* check if compl_curr_match has changed, (e.g. other type of * expansion added something) */ ! 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,4672 **** || (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; return i; } --- 4666,4681 ---- || (ctrl_x_mode != 0 && !CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode))) i = ins_compl_make_cyclic(); ! 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; } *** ../vim-8.0.0595/src/testdir/test_popup.vim 2017-03-18 20:18:42.067950195 +0100 --- src/testdir/test_popup.vim 2017-05-01 20:37:54.266704840 +0200 *************** *** 570,573 **** --- 570,616 ---- 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\\/\", 'tx') + call assert_equal('Oct/Oct', getline(1)) + bwipe! + set completefunc= + endfunc + + " vim: shiftwidth=2 sts=2 expandtab *** ../vim-8.0.0595/src/version.c 2017-05-01 14:13:50.846738000 +0200 --- src/version.c 2017-05-01 20:10:16.312565746 +0200 *************** *** 766,767 **** --- 766,769 ---- { /* Add new patch number below this line */ + /**/ + 596, /**/ -- VOICE OVER: As the horrendous Black Beast lunged forward, escape for Arthur and his knights seemed hopeless, when, suddenly ... the animator suffered a fatal heart attack. ANIMATOR: Aaaaagh! VOICE OVER: The cartoon peril was no more ... The Quest for Holy Grail could continue. "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///