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('<amatch>'))
!         au WinScrolled * let g:afile = str2nr(expand('<afile>'))
    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('<amatch>'))
!     au WinScrolled * let g:afile = str2nr(expand('<afile>'))
    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, "\<C-E>")
+   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
    " <amatch> and <afile> 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 -- [email protected] -- http://www.Moolenaar.net   \\\
///                                                                      \\\
\\\        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/20220412103332.DED9A1C1411%40moolenaar.net.

Raspunde prin e-mail lui