To: vim_dev@googlegroups.com Subject: Patch 8.2.4739 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.4739 Problem: Accessing freed memory after WinScrolled autocmd event. Solution: Check the window pointer is still valid. (closes #10156) Remove the argument from may_trigger_winscrolled(). Files: src/window.c, src/proto/window.pro, src/edit.c, src/gui.c, src/main.c, src/testdir/test_autocmd.vim *** ../vim-8.2.4738/src/window.c 2022-04-08 15:17:53.075952529 +0100 --- src/window.c 2022-04-12 11:15:45.830173337 +0100 *************** *** 2784,2792 **** recursive = FALSE; } void ! may_trigger_winscrolled(win_T *wp) { static int recursive = FALSE; char_u winid[NUMBUFLEN]; --- 2784,2796 ---- recursive = FALSE; } + /* + * Trigger WinScrolled for "curwin" if needed. + */ void ! may_trigger_winscrolled(void) { + win_T *wp = curwin; static int recursive = FALSE; char_u winid[NUMBUFLEN]; *************** *** 2804,2813 **** apply_autocmds(EVENT_WINSCROLLED, winid, winid, FALSE, wp->w_buffer); recursive = FALSE; ! wp->w_last_topline = wp->w_topline; ! wp->w_last_leftcol = wp->w_leftcol; ! wp->w_last_width = wp->w_width; ! wp->w_last_height = wp->w_height; } } --- 2808,2821 ---- apply_autocmds(EVENT_WINSCROLLED, winid, winid, FALSE, wp->w_buffer); recursive = FALSE; ! // an autocmd may close the window, "wp" may be invalid now ! if (win_valid_any_tab(wp)) ! { ! wp->w_last_topline = wp->w_topline; ! wp->w_last_leftcol = wp->w_leftcol; ! wp->w_last_width = wp->w_width; ! wp->w_last_height = wp->w_height; ! } } } *** ../vim-8.2.4738/src/proto/window.pro 2022-04-08 15:17:53.075952529 +0100 --- src/proto/window.pro 2022-04-12 11:16:33.006079928 +0100 *************** *** 17,23 **** void close_windows(buf_T *buf, int keep_curwin); int one_window(void); int win_close(win_T *win, int free_buf); ! void may_trigger_winscrolled(win_T *wp); void win_close_othertab(win_T *win, int free_buf, tabpage_T *tp); void win_free_all(void); win_T *winframe_remove(win_T *win, int *dirp, tabpage_T *tp); --- 17,23 ---- void close_windows(buf_T *buf, int keep_curwin); int one_window(void); int win_close(win_T *win, int free_buf); ! void may_trigger_winscrolled(void); void win_close_othertab(win_T *win, int free_buf, tabpage_T *tp); void win_free_all(void); win_T *winframe_remove(win_T *win, int *dirp, tabpage_T *tp); *** ../vim-8.2.4738/src/edit.c 2022-04-09 18:17:30.056746549 +0100 --- src/edit.c 2022-04-12 11:16:03.762137681 +0100 *************** *** 1528,1534 **** } if (ready) ! may_trigger_winscrolled(curwin); // Trigger SafeState if nothing is pending. may_trigger_safestate(ready --- 1528,1534 ---- } if (ready) ! may_trigger_winscrolled(); // Trigger SafeState if nothing is pending. may_trigger_safestate(ready *** ../vim-8.2.4738/src/gui.c 2022-04-08 15:17:53.071952540 +0100 --- src/gui.c 2022-04-12 11:16:13.306118794 +0100 *************** *** 5238,5244 **** } if (!finish_op) ! may_trigger_winscrolled(curwin); # ifdef FEAT_CONCEAL if (conceal_update_lines --- 5238,5244 ---- } if (!finish_op) ! may_trigger_winscrolled(); # ifdef FEAT_CONCEAL if (conceal_update_lines *** ../vim-8.2.4738/src/main.c 2022-04-08 15:17:53.071952540 +0100 --- src/main.c 2022-04-12 11:16:21.150103293 +0100 *************** *** 1342,1348 **** validate_cursor(); if (!finish_op) ! may_trigger_winscrolled(curwin); // If nothing is pending and we are going to wait for the user to // type a character, trigger SafeState. --- 1342,1348 ---- validate_cursor(); if (!finish_op) ! may_trigger_winscrolled(); // If nothing is pending and we are going to wait for the user to // type a character, trigger SafeState. *** ../vim-8.2.4738/src/testdir/test_autocmd.vim 2022-04-10 11:43:58.901332598 +0100 --- src/testdir/test_autocmd.vim 2022-04-12 11:08:51.747067252 +0100 *************** *** 314,330 **** CheckRunVimInTerminal let lines =<< trim END ! set nowrap scrolloff=0 ! for ii in range(1, 18) ! call setline(ii, repeat(nr2char(96 + ii), ii * 2)) ! endfor ! let win_id = win_getid() ! let g:matched = v:false ! execute 'au WinScrolled' win_id 'let g:matched = v:true' ! let g:scrolled = 0 ! au WinScrolled * let g:scrolled += 1 ! au WinScrolled * let g:amatch = str2nr(expand('')) ! au WinScrolled * let g:afile = str2nr(expand('')) END call writefile(lines, 'Xtest_winscrolled') let buf = RunVimInTerminal('-S Xtest_winscrolled', {'rows': 6}) --- 314,330 ---- CheckRunVimInTerminal let lines =<< trim END ! set nowrap scrolloff=0 ! for ii in range(1, 18) ! call setline(ii, repeat(nr2char(96 + ii), ii * 2)) ! endfor ! let win_id = win_getid() ! let g:matched = v:false ! execute 'au WinScrolled' win_id 'let g:matched = v:true' ! let g:scrolled = 0 ! au WinScrolled * let g:scrolled += 1 ! au WinScrolled * let g:amatch = str2nr(expand('')) ! au WinScrolled * let g:afile = str2nr(expand('')) END call writefile(lines, 'Xtest_winscrolled') let buf = RunVimInTerminal('-S Xtest_winscrolled', {'rows': 6}) *************** *** 364,369 **** --- 364,393 ---- call delete('Xtest_winscrolled') endfunc + func Test_WinScrolled_close_curwin() + CheckRunVimInTerminal + + let lines =<< trim END + set nowrap scrolloff=0 + call setline(1, ['aaa', 'bbb']) + vsplit + au WinScrolled * close + au VimLeave * call writefile(['123456'], 'Xtestout') + END + call writefile(lines, 'Xtest_winscrolled_close_curwin') + let buf = RunVimInTerminal('-S Xtest_winscrolled_close_curwin', {'rows': 6}) + + " This was using freed memory + call term_sendkeys(buf, "\") + call TermWait(buf) + call StopVimInTerminal(buf) + + call assert_equal(['123456'], readfile('Xtestout')) + + call delete('Xtest_winscrolled_close_curwin') + call delete('Xtestout') + endfunc + func Test_WinClosed() " Test that the pattern is matched against the closed window's ID, and both " and are set to it. *** ../vim-8.2.4738/src/version.c 2022-04-11 19:38:15.915471119 +0100 --- src/version.c 2022-04-12 11:10:22.358856916 +0100 *************** *** 748,749 **** --- 748,751 ---- { /* Add new patch number below this line */ + /**/ + 4739, /**/ -- Eye have a spelling checker, it came with my PC; It plainly marks four my revue mistakes I cannot sea. I've run this poem threw it, I'm sure your please to no, It's letter perfect in it's weigh, my checker tolled me sew! /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// \\\ \\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///