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 -- [EMAIL PROTECTED] -- 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    ///

Reply via email to