To: vim_dev@googlegroups.com Subject: Patch 8.0.0079 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.0.0079 Problem: Accessing freed memory in quickfix. (Domenique Pelle) Solution: Do not free the current list when adding to it. Files: src/quickfix.c, src/testdir/test_quickfix.vim *** ../vim-8.0.0078/src/quickfix.c 2016-11-12 15:36:50.284076568 +0100 --- src/quickfix.c 2016-11-12 18:11:19.331186720 +0100 *************** *** 1112,1117 **** --- 1112,1118 ---- qffields_T fields = {NULL, NULL, 0, 0L, 0, FALSE, NULL, 0, 0, 0}; #ifdef FEAT_WINDOWS qfline_T *old_last = NULL; + int adding = FALSE; #endif static efm_T *fmt_first = NULL; char_u *efm; *************** *** 1140,1145 **** --- 1141,1147 ---- else if (qi->qf_lists[qi->qf_curlist].qf_count > 0) { /* Adding to existing list, use last entry. */ + adding = TRUE; old_last = qi->qf_lists[qi->qf_curlist].qf_last; } #endif *************** *** 1266,1275 **** } EMSG(_(e_readerrf)); error2: ! qf_free(qi, qi->qf_curlist); ! qi->qf_listcount--; ! if (qi->qf_curlist > 0) ! --qi->qf_curlist; qf_init_end: if (state.fd != NULL) fclose(state.fd); --- 1268,1280 ---- } EMSG(_(e_readerrf)); error2: ! if (!adding) ! { ! qf_free(qi, qi->qf_curlist); ! qi->qf_listcount--; ! if (qi->qf_curlist > 0) ! --qi->qf_curlist; ! } qf_init_end: if (state.fd != NULL) fclose(state.fd); *** ../vim-8.0.0078/src/testdir/test_quickfix.vim 2016-11-12 15:36:50.288076542 +0100 --- src/testdir/test_quickfix.vim 2016-11-12 18:09:29.515893989 +0100 *************** *** 6,12 **** set encoding=utf-8 ! function! s:setup_commands(cchar) if a:cchar == 'c' command! -nargs=* -bang Xlist clist command! -nargs=* Xgetexpr cgetexpr --- 6,12 ---- set encoding=utf-8 ! func s:setup_commands(cchar) if a:cchar == 'c' command! -nargs=* -bang Xlist clist command! -nargs=* Xgetexpr cgetexpr *************** *** 68,77 **** let g:Xgetlist = function('getloclist', [0]) let g:Xsetlist = function('setloclist', [0]) endif ! endfunction " Tests for the :clist and :llist commands ! function XlistTests(cchar) call s:setup_commands(a:cchar) " With an empty list, command should return error --- 68,77 ---- let g:Xgetlist = function('getloclist', [0]) let g:Xsetlist = function('setloclist', [0]) endif ! endfunc " Tests for the :clist and :llist commands ! func XlistTests(cchar) call s:setup_commands(a:cchar) " With an empty list, command should return error *************** *** 128,144 **** let l = split(result, "\n") call assert_equal([' 2 Xtestfile1:1 col 3: Line1', \ ' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2'], l) ! endfunction ! function Test_clist() call XlistTests('c') call XlistTests('l') ! endfunction " Tests for the :colder, :cnewer, :lolder and :lnewer commands " Note that this test assumes that a quickfix/location list is " already set by the caller. ! function XageTests(cchar) call s:setup_commands(a:cchar) " Jumping to a non existent list should return error --- 128,144 ---- let l = split(result, "\n") call assert_equal([' 2 Xtestfile1:1 col 3: Line1', \ ' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2'], l) ! endfunc ! func Test_clist() call XlistTests('c') call XlistTests('l') ! endfunc " Tests for the :colder, :cnewer, :lolder and :lnewer commands " Note that this test assumes that a quickfix/location list is " already set by the caller. ! func XageTests(cchar) call s:setup_commands(a:cchar) " Jumping to a non existent list should return error *************** *** 171,190 **** Xnewer 2 let l = g:Xgetlist() call assert_equal('Line3', l[0].text) ! endfunction ! function Test_cage() let list = [{'bufnr': 1, 'lnum': 1}] call setqflist(list) call XageTests('c') call setloclist(0, list) call XageTests('l') ! endfunction " Tests for the :cwindow, :lwindow :cclose, :lclose, :copen and :lopen " commands ! function XwindowTests(cchar) call s:setup_commands(a:cchar) " Create a list with no valid entries --- 171,190 ---- Xnewer 2 let l = g:Xgetlist() call assert_equal('Line3', l[0].text) ! endfunc ! func Test_cage() let list = [{'bufnr': 1, 'lnum': 1}] call setqflist(list) call XageTests('c') call setloclist(0, list) call XageTests('l') ! endfunc " Tests for the :cwindow, :lwindow :cclose, :lclose, :copen and :lopen " commands ! func XwindowTests(cchar) call s:setup_commands(a:cchar) " Create a list with no valid entries *************** *** 227,242 **** " Calling cwindow should close the quickfix window with no valid errors Xwindow call assert_true(winnr('$') == 1) ! endfunction ! function Test_cwindow() call XwindowTests('c') call XwindowTests('l') ! endfunction " Tests for the :cfile, :lfile, :caddfile, :laddfile, :cgetfile and :lgetfile " commands. ! function XfileTests(cchar) call s:setup_commands(a:cchar) call writefile(['Xtestfile1:700:10:Line 700', --- 227,242 ---- " Calling cwindow should close the quickfix window with no valid errors Xwindow call assert_true(winnr('$') == 1) ! endfunc ! func Test_cwindow() call XwindowTests('c') call XwindowTests('l') ! endfunc " Tests for the :cfile, :lfile, :caddfile, :laddfile, :cgetfile and :lgetfile " commands. ! func XfileTests(cchar) call s:setup_commands(a:cchar) call writefile(['Xtestfile1:700:10:Line 700', *************** *** 275,290 **** \ l[1].lnum == 333 && l[1].col == 88 && l[1].text ==# 'Line 333') call delete('Xqftestfile1') ! endfunction ! function Test_cfile() call XfileTests('c') call XfileTests('l') ! endfunction " Tests for the :cbuffer, :lbuffer, :caddbuffer, :laddbuffer, :cgetbuffer and " :lgetbuffer commands. ! function XbufferTests(cchar) call s:setup_commands(a:cchar) enew! --- 275,290 ---- \ l[1].lnum == 333 && l[1].col == 88 && l[1].text ==# 'Line 333') call delete('Xqftestfile1') ! endfunc ! func Test_cfile() call XfileTests('c') call XfileTests('l') ! endfunc " Tests for the :cbuffer, :lbuffer, :caddbuffer, :laddbuffer, :cgetbuffer and " :lgetbuffer commands. ! func XbufferTests(cchar) call s:setup_commands(a:cchar) enew! *************** *** 316,341 **** \ l[3].lnum == 750 && l[3].col == 25 && l[3].text ==# 'Line 750') enew! ! endfunction ! function Test_cbuffer() call XbufferTests('c') call XbufferTests('l') ! endfunction ! function XexprTests(cchar) call s:setup_commands(a:cchar) call assert_fails('Xexpr 10', 'E777:') ! endfunction ! function Test_cexpr() call XexprTests('c') call XexprTests('l') ! endfunction " Tests for :cnext, :cprev, :cfirst, :clast commands ! function Xtest_browse(cchar) call s:setup_commands(a:cchar) call s:create_test_file('Xqftestfile1') --- 316,341 ---- \ l[3].lnum == 750 && l[3].col == 25 && l[3].text ==# 'Line 750') enew! ! endfunc ! func Test_cbuffer() call XbufferTests('c') call XbufferTests('l') ! endfunc ! func XexprTests(cchar) call s:setup_commands(a:cchar) call assert_fails('Xexpr 10', 'E777:') ! endfunc ! func Test_cexpr() call XexprTests('c') call XexprTests('l') ! endfunc " Tests for :cnext, :cprev, :cfirst, :clast commands ! func Xtest_browse(cchar) call s:setup_commands(a:cchar) call s:create_test_file('Xqftestfile1') *************** *** 366,379 **** call delete('Xqftestfile1') call delete('Xqftestfile2') ! endfunction ! function Test_browse() call Xtest_browse('c') call Xtest_browse('l') ! endfunction ! function Test_nomem() call test_alloc_fail(GetAllocId('qf_dirname_start'), 0, 0) call assert_fails('vimgrep vim runtest.vim', 'E342:') --- 366,379 ---- call delete('Xqftestfile1') call delete('Xqftestfile2') ! endfunc ! func Test_browse() call Xtest_browse('c') call Xtest_browse('l') ! endfunc ! func Test_nomem() call test_alloc_fail(GetAllocId('qf_dirname_start'), 0, 0) call assert_fails('vimgrep vim runtest.vim', 'E342:') *************** *** 391,397 **** endfunc ! function! s:test_xhelpgrep(cchar) call s:setup_commands(a:cchar) Xhelpgrep quickfix Xopen --- 391,397 ---- endfunc ! func s:test_xhelpgrep(cchar) call s:setup_commands(a:cchar) Xhelpgrep quickfix Xopen *************** *** 403,411 **** call assert_true(w:quickfix_title =~ title_text, w:quickfix_title) " This wipes out the buffer, make sure that doesn't cause trouble. Xclose ! endfunction ! function Test_helpgrep() call s:test_xhelpgrep('c') helpclose call s:test_xhelpgrep('l') --- 403,411 ---- call assert_true(w:quickfix_title =~ title_text, w:quickfix_title) " This wipes out the buffer, make sure that doesn't cause trouble. Xclose ! endfunc ! func Test_helpgrep() call s:test_xhelpgrep('c') helpclose call s:test_xhelpgrep('l') *************** *** 443,449 **** augroup! QfBufWinEnter endfunc ! function XqfTitleTests(cchar) call s:setup_commands(a:cchar) Xgetexpr ['file:1:1:message'] --- 443,449 ---- augroup! QfBufWinEnter endfunc ! func XqfTitleTests(cchar) call s:setup_commands(a:cchar) Xgetexpr ['file:1:1:message'] *************** *** 462,477 **** endif call assert_equal(title, w:quickfix_title) Xclose ! endfunction " Tests for quickfix window's title ! function Test_qf_title() call XqfTitleTests('c') call XqfTitleTests('l') ! endfunction " Tests for 'errorformat' ! function Test_efm() let save_efm = &efm set efm=%EEEE%m,%WWWW%m,%+CCCC%.%#,%-GGGG%.%# cgetexpr ['WWWW', 'EEEE', 'CCCC'] --- 462,477 ---- endif call assert_equal(title, w:quickfix_title) Xclose ! endfunc " Tests for quickfix window's title ! func Test_qf_title() call XqfTitleTests('c') call XqfTitleTests('l') ! endfunc " Tests for 'errorformat' ! func Test_efm() let save_efm = &efm set efm=%EEEE%m,%WWWW%m,%+CCCC%.%#,%-GGGG%.%# cgetexpr ['WWWW', 'EEEE', 'CCCC'] *************** *** 484,490 **** let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]'))) call assert_equal("[['W', 1], ['ZZZZ', 0], ['E^@CCCC', 1], ['YYYY', 0]]", l) let &efm = save_efm ! endfunction " This will test for problems in quickfix: " A. incorrectly copying location lists which caused the location list to show --- 484,490 ---- let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]'))) call assert_equal("[['W', 1], ['ZZZZ', 0], ['E^@CCCC', 1], ['YYYY', 0]]", l) let &efm = save_efm ! endfunc " This will test for problems in quickfix: " A. incorrectly copying location lists which caused the location list to show *************** *** 495,501 **** " window it belongs to. " " Set up the test environment: ! function! ReadTestProtocol(name) let base = substitute(a:name, '\v^test://(.*)%(\.[^.]+)?', '\1', '') let word = substitute(base, '\v(.*)\..*', '\1', '') --- 495,501 ---- " window it belongs to. " " Set up the test environment: ! func ReadTestProtocol(name) let base = substitute(a:name, '\v^test://(.*)%(\.[^.]+)?', '\1', '') let word = substitute(base, '\v(.*)\..*', '\1', '') *************** *** 514,522 **** setl nomodifiable setl readonly exe 'doautocmd BufRead ' . substitute(a:name, '\v^test://(.*)', '\1', '') ! endfunction ! function Test_locationlist() enew augroup testgroup --- 514,522 ---- setl nomodifiable setl readonly exe 'doautocmd BufRead ' . substitute(a:name, '\v^test://(.*)', '\1', '') ! endfunc ! func Test_locationlist() enew augroup testgroup *************** *** 596,610 **** wincmd n | only augroup! testgroup ! endfunction ! function Test_locationlist_curwin_was_closed() augroup testgroup au! autocmd BufReadCmd test_curwin.txt call R(expand("")) augroup END ! function! R(n) quit endfunc --- 596,610 ---- wincmd n | only augroup! testgroup ! endfunc ! func Test_locationlist_curwin_was_closed() augroup testgroup au! autocmd BufReadCmd test_curwin.txt call R(expand("")) augroup END ! func! R(n) quit endfunc *************** *** 615,623 **** call assert_fails('lrewind', 'E924:') augroup! testgroup ! endfunction ! function Test_locationlist_cross_tab_jump() call writefile(['loclistfoo'], 'loclistfoo') call writefile(['loclistbar'], 'loclistbar') set switchbuf=usetab --- 615,623 ---- call assert_fails('lrewind', 'E924:') augroup! testgroup ! endfunc ! func Test_locationlist_cross_tab_jump() call writefile(['loclistfoo'], 'loclistfoo') call writefile(['loclistbar'], 'loclistbar') set switchbuf=usetab *************** *** 631,640 **** set switchbuf&vim call delete('loclistfoo') call delete('loclistbar') ! endfunction " More tests for 'errorformat' ! function! Test_efm1() if !has('unix') " The 'errorformat' setting is different on non-Unix systems. " This test works only on Unix-like systems. --- 631,640 ---- set switchbuf&vim call delete('loclistfoo') call delete('loclistbar') ! endfunc " More tests for 'errorformat' ! func Test_efm1() if !has('unix') " The 'errorformat' setting is different on non-Unix systems. " This test works only on Unix-like systems. *************** *** 752,761 **** call delete('Xerrorfile1') call delete('Xerrorfile2') call delete('Xtestfile') ! endfunction " Test for quickfix directory stack support ! function! s:dir_stack_tests(cchar) call s:setup_commands(a:cchar) let save_efm=&efm --- 752,761 ---- call delete('Xerrorfile1') call delete('Xerrorfile2') call delete('Xtestfile') ! endfunc " Test for quickfix directory stack support ! func s:dir_stack_tests(cchar) call s:setup_commands(a:cchar) let save_efm=&efm *************** *** 797,806 **** call assert_equal(5, qf[11].lnum) let &efm=save_efm ! endfunction " Tests for %D and %X errorformat options ! function! Test_efm_dirstack() " Create the directory stack and files call mkdir('dir1') call mkdir('dir1/a') --- 797,806 ---- call assert_equal(5, qf[11].lnum) let &efm=save_efm ! endfunc " Tests for %D and %X errorformat options ! func Test_efm_dirstack() " Create the directory stack and files call mkdir('dir1') call mkdir('dir1/a') *************** *** 832,841 **** call delete('dir1', 'rf') call delete('dir2', 'rf') call delete('habits1.txt') ! endfunction " Test for resync after continuing an ignored message ! function! Xefm_ignore_continuations(cchar) call s:setup_commands(a:cchar) let save_efm = &efm --- 832,841 ---- call delete('dir1', 'rf') call delete('dir2', 'rf') call delete('habits1.txt') ! endfunc " Test for resync after continuing an ignored message ! func Xefm_ignore_continuations(cchar) call s:setup_commands(a:cchar) let save_efm = &efm *************** *** 850,864 **** call assert_equal([['resync', 1, 4, 'E']], l) let &efm = save_efm ! endfunction ! function! Test_efm_ignore_continuations() call Xefm_ignore_continuations('c') call Xefm_ignore_continuations('l') ! endfunction " Tests for invalid error format specifies ! function Xinvalid_efm_Tests(cchar) call s:setup_commands(a:cchar) let save_efm = &efm --- 850,864 ---- call assert_equal([['resync', 1, 4, 'E']], l) let &efm = save_efm ! endfunc ! func Test_efm_ignore_continuations() call Xefm_ignore_continuations('c') call Xefm_ignore_continuations('l') ! endfunc " Tests for invalid error format specifies ! func Xinvalid_efm_Tests(cchar) call s:setup_commands(a:cchar) let save_efm = &efm *************** *** 891,907 **** call assert_fails('Xexpr ["Entering dir abc", "abc.txt:1:Hello world"]', 'E379:') let &efm = save_efm ! endfunction ! function Test_invalid_efm() call Xinvalid_efm_Tests('c') call Xinvalid_efm_Tests('l') ! endfunction " TODO: " Add tests for the following formats in 'errorformat' " %r %O ! function! Test_efm2() let save_efm = &efm " Test for %s format in efm --- 891,907 ---- call assert_fails('Xexpr ["Entering dir abc", "abc.txt:1:Hello world"]', 'E379:') let &efm = save_efm ! endfunc ! func Test_invalid_efm() call Xinvalid_efm_Tests('c') call Xinvalid_efm_Tests('l') ! endfunc " TODO: " Add tests for the following formats in 'errorformat' " %r %O ! func Test_efm2() let save_efm = &efm " Test for %s format in efm *************** *** 987,1005 **** call assert_equal('unittests/dbfacadeTest.py', bufname(l[4].bufnr)) let &efm = save_efm ! endfunction ! function XquickfixChangedByAutocmd(cchar) call s:setup_commands(a:cchar) if a:cchar == 'c' let ErrorNr = 'E925' ! function! ReadFunc() colder cgetexpr [] endfunc else let ErrorNr = 'E926' ! function! ReadFunc() lolder lgetexpr [] endfunc --- 987,1005 ---- call assert_equal('unittests/dbfacadeTest.py', bufname(l[4].bufnr)) let &efm = save_efm ! endfunc ! func XquickfixChangedByAutocmd(cchar) call s:setup_commands(a:cchar) if a:cchar == 'c' let ErrorNr = 'E925' ! func! ReadFunc() colder cgetexpr [] endfunc else let ErrorNr = 'E926' ! func! ReadFunc() lolder lgetexpr [] endfunc *************** *** 1022,1031 **** augroup! testgroup endfunc ! function Test_quickfix_was_changed_by_autocmd() call XquickfixChangedByAutocmd('c') call XquickfixChangedByAutocmd('l') ! endfunction func Test_caddbuffer_to_empty() helpgr quickfix --- 1022,1031 ---- augroup! testgroup endfunc ! func Test_quickfix_was_changed_by_autocmd() call XquickfixChangedByAutocmd('c') call XquickfixChangedByAutocmd('l') ! endfunc func Test_caddbuffer_to_empty() helpgr quickfix *************** *** 1047,1053 **** endfunc " Tests for the setqflist() and setloclist() functions ! function SetXlistTests(cchar, bnum) call s:setup_commands(a:cchar) call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 1}, --- 1047,1053 ---- endfunc " Tests for the setqflist() and setloclist() functions ! func SetXlistTests(cchar, bnum) call s:setup_commands(a:cchar) call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 1}, *************** *** 1082,1090 **** call g:Xsetlist([]) let l = g:Xgetlist() call assert_equal(0, len(l)) ! endfunction ! function Test_setqflist() new Xtestfile | only let bnum = bufnr('%') call setline(1, range(1,5)) --- 1082,1090 ---- call g:Xsetlist([]) let l = g:Xgetlist() call assert_equal(0, len(l)) ! endfunc ! func Test_setqflist() new Xtestfile | only let bnum = bufnr('%') call setline(1, range(1,5)) *************** *** 1094,1102 **** enew! call delete('Xtestfile') ! endfunction ! function Xlist_empty_middle(cchar) call s:setup_commands(a:cchar) " create three quickfix lists --- 1094,1102 ---- enew! call delete('Xtestfile') ! endfunc ! func Xlist_empty_middle(cchar) call s:setup_commands(a:cchar) " create three quickfix lists *************** *** 1119,1130 **** call assert_equal(matchlen, len(g:Xgetlist())) endfunc ! function Test_setqflist_empty_middle() call Xlist_empty_middle('c') call Xlist_empty_middle('l') ! endfunction ! function Xlist_empty_older(cchar) call s:setup_commands(a:cchar) " create three quickfix lists --- 1119,1130 ---- call assert_equal(matchlen, len(g:Xgetlist())) endfunc ! func Test_setqflist_empty_middle() call Xlist_empty_middle('c') call Xlist_empty_middle('l') ! endfunc ! func Xlist_empty_older(cchar) call s:setup_commands(a:cchar) " create three quickfix lists *************** *** 1145,1158 **** call assert_equal(twolen, len(g:Xgetlist())) Xnewer call assert_equal(threelen, len(g:Xgetlist())) ! endfunction ! function Test_setqflist_empty_older() call Xlist_empty_older('c') call Xlist_empty_older('l') ! endfunction ! function! XquickfixSetListWithAct(cchar) call s:setup_commands(a:cchar) let list1 = [{'filename': 'fnameA', 'text': 'A'}, --- 1145,1158 ---- call assert_equal(twolen, len(g:Xgetlist())) Xnewer call assert_equal(threelen, len(g:Xgetlist())) ! endfunc ! func Test_setqflist_empty_older() call Xlist_empty_older('c') call Xlist_empty_older('l') ! endfunc ! func XquickfixSetListWithAct(cchar) call s:setup_commands(a:cchar) let list1 = [{'filename': 'fnameA', 'text': 'A'}, *************** *** 1226,1237 **** call assert_fails("call g:Xsetlist(list1, 0)", 'E928:') endfunc ! function Test_quickfix_set_list_with_act() call XquickfixSetListWithAct('c') call XquickfixSetListWithAct('l') ! endfunction ! function XLongLinesTests(cchar) let l = g:Xgetlist() call assert_equal(4, len(l)) --- 1226,1237 ---- call assert_fails("call g:Xsetlist(list1, 0)", 'E928:') endfunc ! func Test_quickfix_set_list_with_act() call XquickfixSetListWithAct('c') call XquickfixSetListWithAct('l') ! endfunc ! func XLongLinesTests(cchar) let l = g:Xgetlist() call assert_equal(4, len(l)) *************** *** 1249,1257 **** call assert_equal(10, len(l[3].text)) call g:Xsetlist([], 'r') ! endfunction ! function s:long_lines_tests(cchar) call s:setup_commands(a:cchar) let testfile = 'samples/quickfix.txt' --- 1249,1257 ---- call assert_equal(10, len(l[3].text)) call g:Xsetlist([], 'r') ! endfunc ! func s:long_lines_tests(cchar) call s:setup_commands(a:cchar) let testfile = 'samples/quickfix.txt' *************** *** 1272,1293 **** exe 'edit' testfile exe 'Xbuffer' bufnr('%') call XLongLinesTests(a:cchar) ! endfunction ! function Test_long_lines() call s:long_lines_tests('c') call s:long_lines_tests('l') ! endfunction ! function! s:create_test_file(filename) let l = [] for i in range(1, 20) call add(l, 'Line' . i) endfor call writefile(l, a:filename) ! endfunction ! function! Test_switchbuf() call s:create_test_file('Xqftestfile1') call s:create_test_file('Xqftestfile2') call s:create_test_file('Xqftestfile3') --- 1272,1293 ---- exe 'edit' testfile exe 'Xbuffer' bufnr('%') call XLongLinesTests(a:cchar) ! endfunc ! func Test_long_lines() call s:long_lines_tests('c') call s:long_lines_tests('l') ! endfunc ! func s:create_test_file(filename) let l = [] for i in range(1, 20) call add(l, 'Line' . i) endfor call writefile(l, a:filename) ! endfunc ! func Test_switchbuf() call s:create_test_file('Xqftestfile1') call s:create_test_file('Xqftestfile2') call s:create_test_file('Xqftestfile3') *************** *** 1374,1382 **** call delete('Xqftestfile1') call delete('Xqftestfile2') call delete('Xqftestfile3') ! endfunction ! function! Xadjust_qflnum(cchar) call s:setup_commands(a:cchar) enew | only --- 1374,1382 ---- call delete('Xqftestfile1') call delete('Xqftestfile2') call delete('Xqftestfile3') ! endfunc ! func Xadjust_qflnum(cchar) call s:setup_commands(a:cchar) enew | only *************** *** 1401,1417 **** enew! call delete(fname) ! endfunction ! function! Test_adjust_lnum() call setloclist(0, []) call Xadjust_qflnum('c') call setqflist([]) call Xadjust_qflnum('l') ! endfunction " Tests for the :grep/:lgrep and :grepadd/:lgrepadd commands ! function! s:test_xgrep(cchar) call s:setup_commands(a:cchar) " The following lines are used for the grep test. Don't remove. --- 1401,1417 ---- enew! call delete(fname) ! endfunc ! func Test_adjust_lnum() call setloclist(0, []) call Xadjust_qflnum('c') call setqflist([]) call Xadjust_qflnum('l') ! endfunc " Tests for the :grep/:lgrep and :grepadd/:lgrepadd commands ! func s:test_xgrep(cchar) call s:setup_commands(a:cchar) " The following lines are used for the grep test. Don't remove. *************** *** 1430,1438 **** set makeef=Temp_File_## silent Xgrepadd GrepAdd_Test_Text: test_quickfix.vim call assert_true(len(g:Xgetlist()) == 6) ! endfunction ! function! Test_grep() if !has('unix') " The grepprg may not be set on non-Unix systems return --- 1430,1438 ---- set makeef=Temp_File_## silent Xgrepadd GrepAdd_Test_Text: test_quickfix.vim call assert_true(len(g:Xgetlist()) == 6) ! endfunc ! func Test_grep() if !has('unix') " The grepprg may not be set on non-Unix systems return *************** *** 1440,1448 **** call s:test_xgrep('c') call s:test_xgrep('l') ! endfunction ! function! Test_two_windows() " Use one 'errorformat' for two windows. Add an expression to each of them, " make sure they each keep their own state. set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f' --- 1440,1448 ---- call s:test_xgrep('c') call s:test_xgrep('l') ! endfunc ! func Test_two_windows() " Use one 'errorformat' for two windows. Add an expression to each of them, " make sure they each keep their own state. set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f' *************** *** 1483,1489 **** call delete('Xtwo', 'rf') endfunc ! function XbottomTests(cchar) call s:setup_commands(a:cchar) call g:Xsetlist([{'filename': 'foo', 'lnum': 42}]) --- 1483,1489 ---- call delete('Xtwo', 'rf') endfunc ! func XbottomTests(cchar) call s:setup_commands(a:cchar) call g:Xsetlist([{'filename': 'foo', 'lnum': 42}]) *************** *** 1499,1510 **** endfunc " Tests for the :cbottom and :lbottom commands ! function Test_cbottom() call XbottomTests('c') call XbottomTests('l') ! endfunction ! function HistoryTest(cchar) call s:setup_commands(a:cchar) call assert_fails(a:cchar . 'older 99', 'E380:') --- 1499,1510 ---- endfunc " Tests for the :cbottom and :lbottom commands ! func Test_cbottom() call XbottomTests('c') call XbottomTests('l') ! endfunc ! func HistoryTest(cchar) call s:setup_commands(a:cchar) call assert_fails(a:cchar . 'older 99', 'E380:') *************** *** 1544,1550 **** endfunc " Quickfix/Location list set/get properties tests ! function Xproperty_tests(cchar) call s:setup_commands(a:cchar) " Error cases --- 1544,1550 ---- endfunc " Quickfix/Location list set/get properties tests ! func Xproperty_tests(cchar) call s:setup_commands(a:cchar) " Error cases *************** *** 1590,1608 **** if a:cchar == 'l' call assert_equal({}, getloclist(99, {'title': 1})) endif ! endfunction ! function Test_qf_property() call Xproperty_tests('c') call Xproperty_tests('l') ! endfunction " Tests for the QuickFixCmdPre/QuickFixCmdPost autocommands ! function QfAutoCmdHandler(loc, cmd) call add(g:acmds, a:loc . a:cmd) ! endfunction ! function Test_Autocmd() autocmd QuickFixCmdPre * call QfAutoCmdHandler('pre', expand('')) autocmd QuickFixCmdPost * call QfAutoCmdHandler('post', expand('')) --- 1590,1608 ---- if a:cchar == 'l' call assert_equal({}, getloclist(99, {'title': 1})) endif ! endfunc ! func Test_qf_property() call Xproperty_tests('c') call Xproperty_tests('l') ! endfunc " Tests for the QuickFixCmdPre/QuickFixCmdPost autocommands ! func QfAutoCmdHandler(loc, cmd) call add(g:acmds, a:loc . a:cmd) ! endfunc ! func Test_Autocmd() autocmd QuickFixCmdPre * call QfAutoCmdHandler('pre', expand('')) autocmd QuickFixCmdPost * call QfAutoCmdHandler('post', expand('')) *************** *** 1630,1638 **** \ 'precaddbuffer', \ 'postcaddbuffer'] call assert_equal(l, g:acmds) ! endfunction ! function! Test_Autocmd_Exception() set efm=%m lgetexpr '?' --- 1630,1638 ---- \ 'precaddbuffer', \ 'postcaddbuffer'] call assert_equal(l, g:acmds) ! endfunc ! func Test_Autocmd_Exception() set efm=%m lgetexpr '?' *************** *** 1647,1660 **** call assert_equal('1', getloclist(0)[0].text) set efm&vim ! endfunction ! function Test_caddbuffer() ! " This used to cause a memory access in freed memory let save_efm = &efm set efm=%EEEE%m,%WWWW,%+CCCC%>%#,%GGGG%.# cgetexpr ['WWWW', 'EEEE', 'CCCC'] let &efm = save_efm ! cad bwipe! endfunc --- 1647,1671 ---- call assert_equal('1', getloclist(0)[0].text) set efm&vim ! endfunc ! func Test_caddbuffer_wrong() ! " This used to cause a memory access in freed memory. let save_efm = &efm set efm=%EEEE%m,%WWWW,%+CCCC%>%#,%GGGG%.# cgetexpr ['WWWW', 'EEEE', 'CCCC'] let &efm = save_efm ! caddbuffer bwipe! endfunc + + func Test_caddexpr_wrong() + " This used to cause a memory access in freed memory. + cbuffer + cbuffer + copen + let save_efm = &efm + set efm=% + call assert_fails('caddexpr ""', 'E376:') + let &efm = save_efm + endfunc *** ../vim-8.0.0078/src/version.c 2016-11-12 15:36:50.288076542 +0100 --- src/version.c 2016-11-12 18:14:08.246098751 +0100 *************** *** 766,767 **** --- 766,769 ---- { /* Add new patch number below this line */ + /**/ + 79, /**/ -- hundred-and-one symptoms of being an internet addict: 20. When looking at a pageful of someone else's links, you notice all of them are already highlighted in purple. /// 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 ///