Blob Blame History Raw
To: vim-dev@vim.org
Subject: patch 7.0.183
Fcc: outbox
From: Bram Moolenaar <Bram@moolenaar.net>
Mime-Version: 1.0
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 8bit
------------

Patch 7.0.183
Problem:    Crash in ":let" when redirecting to a variable that's being
	    displayed. (Thomas Link)
Solution:   When redirecting to a variable only do the assignment when
	    stopping redirection to avoid that setting the variable causes a
	    freed string to be accessed.
Files:	    src/eval.c


*** ../vim-7.0.182/src/eval.c	Tue Dec  5 10:33:57 2006
--- src/eval.c	Sun Jan 14 14:20:49 2007
***************
*** 898,903 ****
--- 898,904 ----
  }
  
  static lval_T	*redir_lval = NULL;
+ static garray_T redir_ga;	/* only valid when redir_lval is not NULL */
  static char_u	*redir_endp = NULL;
  static char_u	*redir_varname = NULL;
  
***************
*** 932,937 ****
--- 933,941 ----
  	return FAIL;
      }
  
+     /* The output is stored in growarray "redir_ga" until redirection ends. */
+     ga_init2(&redir_ga, (int)sizeof(char), 500);
+ 
      /* Parse the variable name (can be a dict or list entry). */
      redir_endp = get_lval(redir_varname, NULL, redir_lval, FALSE, FALSE, FALSE,
  							     FNE_CHECK_START);
***************
*** 974,1015 ****
  }
  
  /*
!  * Append "value[len]" to the variable set by var_redir_start().
   */
      void
! var_redir_str(value, len)
      char_u	*value;
!     int		len;
  {
!     char_u	*val;
!     typval_T	tv;
!     int		save_emsg;
!     int		err;
  
      if (redir_lval == NULL)
  	return;
  
!     if (len == -1)
! 	/* Append the entire string */
! 	val = vim_strsave(value);
!     else
! 	/* Append only the specified number of characters */
! 	val = vim_strnsave(value, len);
!     if (val == NULL)
! 	return;
! 
!     tv.v_type = VAR_STRING;
!     tv.vval.v_string = val;
  
!     save_emsg = did_emsg;
!     did_emsg = FALSE;
!     set_var_lval(redir_lval, redir_endp, &tv, FALSE, (char_u *)".");
!     err = did_emsg;
!     did_emsg |= save_emsg;
!     if (err)
  	var_redir_stop();
- 
-     vim_free(tv.vval.v_string);
  }
  
  /*
--- 978,1013 ----
  }
  
  /*
!  * Append "value[value_len]" to the variable set by var_redir_start().
!  * The actual appending is postponed until redirection ends, because the value
!  * appended may in fact be the string we write to, changing it may cause freed
!  * memory to be used:
!  *   :redir => foo
!  *   :let foo
!  *   :redir END
   */
      void
! var_redir_str(value, value_len)
      char_u	*value;
!     int		value_len;
  {
!     size_t	len;
  
      if (redir_lval == NULL)
  	return;
  
!     if (value_len == -1)
! 	len = STRLEN(value);	/* Append the entire string */
!     else
! 	len = value_len;	/* Append only "value_len" characters */
  
!     if (ga_grow(&redir_ga, (int)len) == OK)
!     {
! 	mch_memmove((char *)redir_ga.ga_data + redir_ga.ga_len, value, len);
! 	redir_ga.ga_len += len;
!     }
!     else
  	var_redir_stop();
  }
  
  /*
***************
*** 1018,1025 ****
--- 1016,1034 ----
      void
  var_redir_stop()
  {
+     typval_T	tv;
+ 
      if (redir_lval != NULL)
      {
+ 	/* Append the trailing NUL. */
+ 	ga_append(&redir_ga, NUL);
+ 
+ 	/* Assign the text to the variable. */
+ 	tv.v_type = VAR_STRING;
+ 	tv.vval.v_string = redir_ga.ga_data;
+ 	set_var_lval(redir_lval, redir_endp, &tv, FALSE, (char_u *)".");
+ 	vim_free(tv.vval.v_string);
+ 
  	clear_lval(redir_lval);
  	vim_free(redir_lval);
  	redir_lval = NULL;
*** ../vim-7.0.182/src/version.c	Tue Jan  9 20:29:55 2007
--- src/version.c	Sun Jan 14 15:23:23 2007
***************
*** 668,669 ****
--- 668,671 ----
  {   /* Add new patch number below this line */
+ /**/
+     183,
  /**/

-- 
How To Keep A Healthy Level Of Insanity:
16. Have your coworkers address you by your wrestling name, Rock Hard Kim.

 /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\        download, build and distribute -- http://www.A-A-P.org        ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///