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 ///