Karsten Hopp ff1bac
To: vim-dev@vim.org
Karsten Hopp ff1bac
Subject: Patch 7.2.445
Karsten Hopp ff1bac
Fcc: outbox
Karsten Hopp ff1bac
From: Bram Moolenaar <Bram@moolenaar.net>
Karsten Hopp ff1bac
Mime-Version: 1.0
Karsten Hopp ff1bac
Content-Type: text/plain; charset=UTF-8
Karsten Hopp ff1bac
Content-Transfer-Encoding: 8bit
Karsten Hopp ff1bac
------------
Karsten Hopp ff1bac
Karsten Hopp ff1bac
Patch 7.2.445
Karsten Hopp ff1bac
Problem:    Crash when using undo/redo and a FileChangedRO autocmd event that
Karsten Hopp ff1bac
	    reloads the buffer. (Dominique Pelle)
Karsten Hopp ff1bac
Solution:   Do not allow autocommands while performing and undo or redo.
Karsten Hopp ff1bac
Files:	    src/misc1.c, src/undo.c
Karsten Hopp ff1bac
Karsten Hopp ff1bac
Karsten Hopp ff1bac
*** ../vim-7.2.444/src/misc1.c	2010-03-23 18:22:40.000000000 +0100
Karsten Hopp ff1bac
--- src/misc1.c	2010-07-07 18:18:52.000000000 +0200
Karsten Hopp ff1bac
***************
Karsten Hopp ff1bac
*** 2467,2476 ****
Karsten Hopp ff1bac
  }
Karsten Hopp ff1bac
  
Karsten Hopp ff1bac
  /*
Karsten Hopp ff1bac
!  * changed() is called when something in the current buffer is changed.
Karsten Hopp ff1bac
   *
Karsten Hopp ff1bac
   * Most often called through changed_bytes() and changed_lines(), which also
Karsten Hopp ff1bac
   * mark the area of the display to be redrawn.
Karsten Hopp ff1bac
   */
Karsten Hopp ff1bac
      void
Karsten Hopp ff1bac
  changed()
Karsten Hopp ff1bac
--- 2467,2478 ----
Karsten Hopp ff1bac
  }
Karsten Hopp ff1bac
  
Karsten Hopp ff1bac
  /*
Karsten Hopp ff1bac
!  * Call this function when something in the current buffer is changed.
Karsten Hopp ff1bac
   *
Karsten Hopp ff1bac
   * Most often called through changed_bytes() and changed_lines(), which also
Karsten Hopp ff1bac
   * mark the area of the display to be redrawn.
Karsten Hopp ff1bac
+  *
Karsten Hopp ff1bac
+  * Careful: may trigger autocommands that reload the buffer.
Karsten Hopp ff1bac
   */
Karsten Hopp ff1bac
      void
Karsten Hopp ff1bac
  changed()
Karsten Hopp ff1bac
***************
Karsten Hopp ff1bac
*** 2536,2541 ****
Karsten Hopp ff1bac
--- 2538,2544 ----
Karsten Hopp ff1bac
   * - marks the windows on this buffer to be redisplayed
Karsten Hopp ff1bac
   * - marks the buffer changed by calling changed()
Karsten Hopp ff1bac
   * - invalidates cached values
Karsten Hopp ff1bac
+  * Careful: may trigger autocommands that reload the buffer.
Karsten Hopp ff1bac
   */
Karsten Hopp ff1bac
      void
Karsten Hopp ff1bac
  changed_bytes(lnum, col)
Karsten Hopp ff1bac
***************
Karsten Hopp ff1bac
*** 2649,2654 ****
Karsten Hopp ff1bac
--- 2652,2658 ----
Karsten Hopp ff1bac
   * below the changed lines (BEFORE the change).
Karsten Hopp ff1bac
   * When only inserting lines, "lnum" and "lnume" are equal.
Karsten Hopp ff1bac
   * Takes care of calling changed() and updating b_mod_*.
Karsten Hopp ff1bac
+  * Careful: may trigger autocommands that reload the buffer.
Karsten Hopp ff1bac
   */
Karsten Hopp ff1bac
      void
Karsten Hopp ff1bac
  changed_lines(lnum, col, lnume, xtra)
Karsten Hopp ff1bac
***************
Karsten Hopp ff1bac
*** 2716,2721 ****
Karsten Hopp ff1bac
--- 2720,2730 ----
Karsten Hopp ff1bac
      }
Karsten Hopp ff1bac
  }
Karsten Hopp ff1bac
  
Karsten Hopp ff1bac
+ /*
Karsten Hopp ff1bac
+  * Common code for when a change is was made.
Karsten Hopp ff1bac
+  * See changed_lines() for the arguments.
Karsten Hopp ff1bac
+  * Careful: may trigger autocommands that reload the buffer.
Karsten Hopp ff1bac
+  */
Karsten Hopp ff1bac
      static void
Karsten Hopp ff1bac
  changed_common(lnum, col, lnume, xtra)
Karsten Hopp ff1bac
      linenr_T	lnum;
Karsten Hopp ff1bac
***************
Karsten Hopp ff1bac
*** 2966,2971 ****
Karsten Hopp ff1bac
--- 2975,2981 ----
Karsten Hopp ff1bac
   * Don't use emsg(), because it flushes the macro buffer.
Karsten Hopp ff1bac
   * If we have undone all changes b_changed will be FALSE, but "b_did_warn"
Karsten Hopp ff1bac
   * will be TRUE.
Karsten Hopp ff1bac
+  * Careful: may trigger autocommands that reload the buffer.
Karsten Hopp ff1bac
   */
Karsten Hopp ff1bac
      void
Karsten Hopp ff1bac
  change_warning(col)
Karsten Hopp ff1bac
*** ../vim-7.2.444/src/undo.c	2010-05-30 16:55:17.000000000 +0200
Karsten Hopp ff1bac
--- src/undo.c	2010-07-07 18:14:44.000000000 +0200
Karsten Hopp ff1bac
***************
Karsten Hopp ff1bac
*** 185,191 ****
Karsten Hopp ff1bac
      }
Karsten Hopp ff1bac
  }
Karsten Hopp ff1bac
  
Karsten Hopp ff1bac
!     void
Karsten Hopp ff1bac
  u_check(int newhead_may_be_NULL)
Karsten Hopp ff1bac
  {
Karsten Hopp ff1bac
      seen_b_u_newhead = 0;
Karsten Hopp ff1bac
--- 185,191 ----
Karsten Hopp ff1bac
      }
Karsten Hopp ff1bac
  }
Karsten Hopp ff1bac
  
Karsten Hopp ff1bac
!     static void
Karsten Hopp ff1bac
  u_check(int newhead_may_be_NULL)
Karsten Hopp ff1bac
  {
Karsten Hopp ff1bac
      seen_b_u_newhead = 0;
Karsten Hopp ff1bac
***************
Karsten Hopp ff1bac
*** 320,325 ****
Karsten Hopp ff1bac
--- 320,328 ----
Karsten Hopp ff1bac
      return TRUE;
Karsten Hopp ff1bac
  }
Karsten Hopp ff1bac
  
Karsten Hopp ff1bac
+ /*
Karsten Hopp ff1bac
+  * Common code for various ways to save text before a change.
Karsten Hopp ff1bac
+  */
Karsten Hopp ff1bac
      static int
Karsten Hopp ff1bac
  u_savecommon(top, bot, newbot)
Karsten Hopp ff1bac
      linenr_T	top, bot;
Karsten Hopp ff1bac
***************
Karsten Hopp ff1bac
*** 374,380 ****
Karsten Hopp ff1bac
      size = bot - top - 1;
Karsten Hopp ff1bac
  
Karsten Hopp ff1bac
      /*
Karsten Hopp ff1bac
!      * if curbuf->b_u_synced == TRUE make a new header
Karsten Hopp ff1bac
       */
Karsten Hopp ff1bac
      if (curbuf->b_u_synced)
Karsten Hopp ff1bac
      {
Karsten Hopp ff1bac
--- 377,383 ----
Karsten Hopp ff1bac
      size = bot - top - 1;
Karsten Hopp ff1bac
  
Karsten Hopp ff1bac
      /*
Karsten Hopp ff1bac
!      * If curbuf->b_u_synced == TRUE make a new header.
Karsten Hopp ff1bac
       */
Karsten Hopp ff1bac
      if (curbuf->b_u_synced)
Karsten Hopp ff1bac
      {
Karsten Hopp ff1bac
***************
Karsten Hopp ff1bac
*** 709,714 ****
Karsten Hopp ff1bac
--- 712,723 ----
Karsten Hopp ff1bac
  	u_oldcount = -1;
Karsten Hopp ff1bac
      while (count--)
Karsten Hopp ff1bac
      {
Karsten Hopp ff1bac
+ 	/* Do the change warning now, so that it triggers FileChangedRO when
Karsten Hopp ff1bac
+ 	 * needed.  This may cause the file to be reloaded, that must happen
Karsten Hopp ff1bac
+ 	 * before we do anything, because it may change curbuf->b_u_curhead
Karsten Hopp ff1bac
+ 	 * and more. */
Karsten Hopp ff1bac
+ 	change_warning(0);
Karsten Hopp ff1bac
+ 
Karsten Hopp ff1bac
  	if (undo_undoes)
Karsten Hopp ff1bac
  	{
Karsten Hopp ff1bac
  	    if (curbuf->b_u_curhead == NULL)		/* first undo */
Karsten Hopp ff1bac
***************
Karsten Hopp ff1bac
*** 952,959 ****
Karsten Hopp ff1bac
  	/*
Karsten Hopp ff1bac
  	 * First go up the tree as much as needed.
Karsten Hopp ff1bac
  	 */
Karsten Hopp ff1bac
! 	for (;;)
Karsten Hopp ff1bac
  	{
Karsten Hopp ff1bac
  	    uhp = curbuf->b_u_curhead;
Karsten Hopp ff1bac
  	    if (uhp == NULL)
Karsten Hopp ff1bac
  		uhp = curbuf->b_u_newhead;
Karsten Hopp ff1bac
--- 961,971 ----
Karsten Hopp ff1bac
  	/*
Karsten Hopp ff1bac
  	 * First go up the tree as much as needed.
Karsten Hopp ff1bac
  	 */
Karsten Hopp ff1bac
! 	while (!got_int)
Karsten Hopp ff1bac
  	{
Karsten Hopp ff1bac
+ 	    /* Do the change warning now, for the same reason as above. */
Karsten Hopp ff1bac
+ 	    change_warning(0);
Karsten Hopp ff1bac
+ 
Karsten Hopp ff1bac
  	    uhp = curbuf->b_u_curhead;
Karsten Hopp ff1bac
  	    if (uhp == NULL)
Karsten Hopp ff1bac
  		uhp = curbuf->b_u_newhead;
Karsten Hopp ff1bac
***************
Karsten Hopp ff1bac
*** 970,978 ****
Karsten Hopp ff1bac
  	/*
Karsten Hopp ff1bac
  	 * And now go down the tree (redo), branching off where needed.
Karsten Hopp ff1bac
  	 */
Karsten Hopp ff1bac
! 	uhp = curbuf->b_u_curhead;
Karsten Hopp ff1bac
! 	while (uhp != NULL)
Karsten Hopp ff1bac
  	{
Karsten Hopp ff1bac
  	    /* Go back to the first branch with a mark. */
Karsten Hopp ff1bac
  	    while (uhp->uh_alt_prev != NULL
Karsten Hopp ff1bac
  					&& uhp->uh_alt_prev->uh_walk == mark)
Karsten Hopp ff1bac
--- 982,996 ----
Karsten Hopp ff1bac
  	/*
Karsten Hopp ff1bac
  	 * And now go down the tree (redo), branching off where needed.
Karsten Hopp ff1bac
  	 */
Karsten Hopp ff1bac
! 	while (!got_int)
Karsten Hopp ff1bac
  	{
Karsten Hopp ff1bac
+ 	    /* Do the change warning now, for the same reason as above. */
Karsten Hopp ff1bac
+ 	    change_warning(0);
Karsten Hopp ff1bac
+ 
Karsten Hopp ff1bac
+ 	    uhp = curbuf->b_u_curhead;
Karsten Hopp ff1bac
+ 	    if (uhp == NULL)
Karsten Hopp ff1bac
+ 		break;
Karsten Hopp ff1bac
+ 
Karsten Hopp ff1bac
  	    /* Go back to the first branch with a mark. */
Karsten Hopp ff1bac
  	    while (uhp->uh_alt_prev != NULL
Karsten Hopp ff1bac
  					&& uhp->uh_alt_prev->uh_walk == mark)
Karsten Hopp ff1bac
***************
Karsten Hopp ff1bac
*** 1070,1075 ****
Karsten Hopp ff1bac
--- 1088,1099 ----
Karsten Hopp ff1bac
      int		empty_buffer;		    /* buffer became empty */
Karsten Hopp ff1bac
      u_header_T	*curhead = curbuf->b_u_curhead;
Karsten Hopp ff1bac
  
Karsten Hopp ff1bac
+ #ifdef FEAT_AUTOCMD
Karsten Hopp ff1bac
+     /* Don't want autocommands using the undo structures here, they are
Karsten Hopp ff1bac
+      * invalid till the end. */
Karsten Hopp ff1bac
+     block_autocmds();
Karsten Hopp ff1bac
+ #endif
Karsten Hopp ff1bac
+ 
Karsten Hopp ff1bac
  #ifdef U_DEBUG
Karsten Hopp ff1bac
      u_check(FALSE);
Karsten Hopp ff1bac
  #endif
Karsten Hopp ff1bac
***************
Karsten Hopp ff1bac
*** 1099,1104 ****
Karsten Hopp ff1bac
--- 1123,1131 ----
Karsten Hopp ff1bac
  	if (top > curbuf->b_ml.ml_line_count || top >= bot
Karsten Hopp ff1bac
  				      || bot > curbuf->b_ml.ml_line_count + 1)
Karsten Hopp ff1bac
  	{
Karsten Hopp ff1bac
+ #ifdef FEAT_AUTOCMD
Karsten Hopp ff1bac
+ 	    unblock_autocmds();
Karsten Hopp ff1bac
+ #endif
Karsten Hopp ff1bac
  	    EMSG(_("E438: u_undo: line numbers wrong"));
Karsten Hopp ff1bac
  	    changed();		/* don't want UNCHANGED now */
Karsten Hopp ff1bac
  	    return;
Karsten Hopp ff1bac
***************
Karsten Hopp ff1bac
*** 1304,1309 ****
Karsten Hopp ff1bac
--- 1331,1340 ----
Karsten Hopp ff1bac
      /* The timestamp can be the same for multiple changes, just use the one of
Karsten Hopp ff1bac
       * the undone/redone change. */
Karsten Hopp ff1bac
      curbuf->b_u_seq_time = curhead->uh_time;
Karsten Hopp ff1bac
+ 
Karsten Hopp ff1bac
+ #ifdef FEAT_AUTOCMD
Karsten Hopp ff1bac
+     unblock_autocmds();
Karsten Hopp ff1bac
+ #endif
Karsten Hopp ff1bac
  #ifdef U_DEBUG
Karsten Hopp ff1bac
      u_check(FALSE);
Karsten Hopp ff1bac
  #endif
Karsten Hopp ff1bac
*** ../vim-7.2.444/src/version.c	2010-06-13 02:35:41.000000000 +0200
Karsten Hopp ff1bac
--- src/version.c	2010-07-07 18:18:27.000000000 +0200
Karsten Hopp ff1bac
***************
Karsten Hopp ff1bac
*** 683,684 ****
Karsten Hopp ff1bac
--- 683,686 ----
Karsten Hopp ff1bac
  {   /* Add new patch number below this line */
Karsten Hopp ff1bac
+ /**/
Karsten Hopp ff1bac
+     445,
Karsten Hopp ff1bac
  /**/
Karsten Hopp ff1bac
Karsten Hopp ff1bac
-- 
Karsten Hopp ff1bac
    A KNIGHT rides into shot and hacks him to the ground.  He rides off.
Karsten Hopp ff1bac
    We stay for a moment on the glade.  A MIDDLE-AGED LADY in a C. & A.
Karsten Hopp ff1bac
    twin-set emerges from the trees and looks in horror at the body of her
Karsten Hopp ff1bac
    HUSBAND.
Karsten Hopp ff1bac
MRS HISTORIAN: FRANK!
Karsten Hopp ff1bac
                 "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD
Karsten Hopp ff1bac
Karsten Hopp ff1bac
 /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net   \\\
Karsten Hopp ff1bac
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
Karsten Hopp ff1bac
\\\        download, build and distribute -- http://www.A-A-P.org        ///
Karsten Hopp ff1bac
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///