To: vim_dev@googlegroups.com Subject: Patch 7.3.715 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 7.3.715 Problem: Crash when calling setloclist() in BufUnload autocmd. (Marcin Szamotulski) Solution: Set w_llist to NULL when it was freed. Also add a test. (Christian Brabandt) Files: src/quickfix.c, src/testdir/test49.ok, src/testdir/test49.vim *** ../vim-7.3.714/src/quickfix.c 2012-06-29 12:57:03.000000000 +0200 --- src/quickfix.c 2012-11-14 22:33:20.000000000 +0100 *************** *** 107,113 **** }; static int qf_init_ext __ARGS((qf_info_T *qi, char_u *efile, buf_T *buf, typval_T *tv, char_u *errorformat, int newlist, linenr_T lnumfirst, linenr_T lnumlast, char_u *qf_title)); ! static void qf_new_list __ARGS((qf_info_T *qi, char_u *qf_title)); static void ll_free_all __ARGS((qf_info_T **pqi)); static int qf_add_entry __ARGS((qf_info_T *qi, qfline_T **prevp, char_u *dir, char_u *fname, int bufnum, char_u *mesg, long lnum, int col, int vis_col, char_u *pattern, int nr, int type, int valid)); static qf_info_T *ll_new_list __ARGS((void)); --- 107,113 ---- }; static int qf_init_ext __ARGS((qf_info_T *qi, char_u *efile, buf_T *buf, typval_T *tv, char_u *errorformat, int newlist, linenr_T lnumfirst, linenr_T lnumlast, char_u *qf_title)); ! static void qf_new_list __ARGS((qf_info_T *qi, char_u *qf_title, win_T *wp)); static void ll_free_all __ARGS((qf_info_T **pqi)); static int qf_add_entry __ARGS((qf_info_T *qi, qfline_T **prevp, char_u *dir, char_u *fname, int bufnum, char_u *mesg, long lnum, int col, int vis_col, char_u *pattern, int nr, int type, int valid)); static qf_info_T *ll_new_list __ARGS((void)); *************** *** 266,272 **** if (newlist || qi->qf_curlist == qi->qf_listcount) /* make place for a new list */ ! qf_new_list(qi, qf_title); else if (qi->qf_lists[qi->qf_curlist].qf_count > 0) /* Adding to existing list, find last entry. */ for (qfprev = qi->qf_lists[qi->qf_curlist].qf_start; --- 266,272 ---- if (newlist || qi->qf_curlist == qi->qf_listcount) /* make place for a new list */ ! qf_new_list(qi, qf_title, curwin); else if (qi->qf_lists[qi->qf_curlist].qf_count > 0) /* Adding to existing list, find last entry. */ for (qfprev = qi->qf_lists[qi->qf_curlist].qf_start; *************** *** 885,893 **** * Prepare for adding a new quickfix list. */ static void ! qf_new_list(qi, qf_title) qf_info_T *qi; char_u *qf_title; { int i; --- 885,894 ---- * Prepare for adding a new quickfix list. */ static void ! qf_new_list(qi, qf_title, wp) qf_info_T *qi; char_u *qf_title; + win_T *wp; { int i; *************** *** 897,903 **** --- 898,908 ---- * way with ":grep'. */ while (qi->qf_listcount > qi->qf_curlist + 1) + { + if (wp != NULL && wp->w_llist == qi) + wp->w_llist = NULL; qf_free(qi, --qi->qf_listcount); + } /* * When the stack is full, remove to oldest entry *************** *** 905,910 **** --- 910,917 ---- */ if (qi->qf_listcount == LISTCOUNT) { + if (wp != NULL && wp->w_llist == qi) + wp->w_llist = NULL; qf_free(qi, 0); for (i = 1; i < LISTCOUNT; ++i) qi->qf_lists[i - 1] = qi->qf_lists[i]; *************** *** 3181,3187 **** eap->cmdidx != CMD_vimgrepadd && eap->cmdidx != CMD_lvimgrepadd) || qi->qf_curlist == qi->qf_listcount) /* make place for a new list */ ! qf_new_list(qi, *eap->cmdlinep); else if (qi->qf_lists[qi->qf_curlist].qf_count > 0) /* Adding to existing list, find last entry. */ for (prevp = qi->qf_lists[qi->qf_curlist].qf_start; --- 3188,3194 ---- eap->cmdidx != CMD_vimgrepadd && eap->cmdidx != CMD_lvimgrepadd) || qi->qf_curlist == qi->qf_listcount) /* make place for a new list */ ! qf_new_list(qi, *eap->cmdlinep, curwin); else if (qi->qf_lists[qi->qf_curlist].qf_count > 0) /* Adding to existing list, find last entry. */ for (prevp = qi->qf_lists[qi->qf_curlist].qf_start; *************** *** 3747,3753 **** if (action == ' ' || qi->qf_curlist == qi->qf_listcount) /* make place for a new list */ ! qf_new_list(qi, title); else if (action == 'a' && qi->qf_lists[qi->qf_curlist].qf_count > 0) /* Adding to existing list, find last entry. */ for (prevp = qi->qf_lists[qi->qf_curlist].qf_start; --- 3754,3760 ---- if (action == ' ' || qi->qf_curlist == qi->qf_listcount) /* make place for a new list */ ! qf_new_list(qi, title, wp); else if (action == 'a' && qi->qf_lists[qi->qf_curlist].qf_count > 0) /* Adding to existing list, find last entry. */ for (prevp = qi->qf_lists[qi->qf_curlist].qf_start; *************** *** 4029,4035 **** #endif /* create a new quickfix list */ ! qf_new_list(qi, *eap->cmdlinep); /* Go through all directories in 'runtimepath' */ p = p_rtp; --- 4036,4042 ---- #endif /* create a new quickfix list */ ! qf_new_list(qi, *eap->cmdlinep, wp); /* Go through all directories in 'runtimepath' */ p = p_rtp; *** ../vim-7.3.714/src/testdir/test49.ok 2010-08-15 21:57:29.000000000 +0200 --- src/testdir/test49.ok 2012-11-14 22:26:13.000000000 +0100 *************** *** 85,92 **** *** Test 83: OK (2835) *** Test 84: OK (934782101) *** Test 85: OK (198689) ! --- Test 86: All tests were run with throwing exceptions on error. The $VIMNOERRTHROW control is not configured. ! --- Test 86: All tests were run with throwing exceptions on interrupt. The $VIMNOINTTHROW control is not configured. ! *** Test 86: OK (50443995) --- 85,94 ---- *** Test 83: OK (2835) *** Test 84: OK (934782101) *** Test 85: OK (198689) ! --- Test 86: No Crash for vimgrep on BufUnload ! *** Test 86: OK (0) ! --- Test 87: All tests were run with throwing exceptions on error. The $VIMNOERRTHROW control is not configured. ! --- Test 87: All tests were run with throwing exceptions on interrupt. The $VIMNOINTTHROW control is not configured. ! *** Test 87: OK (50443995) *** ../vim-7.3.714/src/testdir/test49.vim 2010-09-29 16:55:45.000000000 +0200 --- src/testdir/test49.vim 2012-11-14 22:26:13.000000000 +0100 *************** *** 9603,9611 **** Xcheck 198689 "------------------------------------------------------------------------------- ! " Test 86: $VIMNOERRTHROW and $VIMNOINTTHROW support {{{1 " " It is possible to configure Vim for throwing exceptions on error " or interrupt, controlled by variables $VIMNOERRTHROW and --- 9603,9630 ---- Xcheck 198689 + "------------------------------------------------------------------------------- + " Test 86 setloclist crash {{{1 + " + " Executing a setloclist() on BufUnload shouldn't crash Vim + "------------------------------------------------------------------------------- + + func F + au BufUnload * :call setloclist(0, [{'bufnr':1, 'lnum':1, 'col':1, 'text': 'tango down'}]) + + :lvimgrep /.*/ * + endfunc + + XpathINIT + + ExecAsScript F + + delfunction F + Xout "No Crash for vimgrep on BufUnload" + Xcheck 0 "------------------------------------------------------------------------------- ! " Test 87: $VIMNOERRTHROW and $VIMNOINTTHROW support {{{1 " " It is possible to configure Vim for throwing exceptions on error " or interrupt, controlled by variables $VIMNOERRTHROW and *** ../vim-7.3.714/src/version.c 2012-11-14 20:52:22.000000000 +0100 --- src/version.c 2012-11-14 22:36:45.000000000 +0100 *************** *** 727,728 **** --- 727,730 ---- { /* Add new patch number below this line */ + /**/ + 715, /**/ -- One difference between a man and a machine is that a machine is quiet when well oiled. /// 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 ///