Patch 7.4.1828
Problem:    May try to access buffer that's already freed.
Solution:   When freeing a buffer remove it from any channel.
Files:      src/buffer.c, src/channel.c, src/proto/channel.pro


*** ../vim-7.4.1827/src/buffer.c        2016-03-19 22:11:47.412675093 +0100
--- src/buffer.c        2016-05-09 20:30:02.966071124 +0200
***************
*** 676,681 ****
--- 676,684 ----
  #ifdef FEAT_RUBY
      ruby_buffer_free(buf);
  #endif
+ #ifdef FEAT_JOB_CHANNEL
+     channel_buffer_free(buf);
+ #endif
  #ifdef FEAT_AUTOCMD
      aubuflocal_remove(buf);
      if (autocmd_busy)
*** ../vim-7.4.1827/src/channel.c       2016-05-09 17:57:59.814722474 +0200
--- src/channel.c       2016-05-09 20:35:09.654594727 +0200
***************
*** 1068,1073 ****
--- 1068,1074 ----
  
  /*
   * Find a buffer matching "name" or create a new one.
+  * Returns NULL if there is something very wrong (error already reported).
   */
      static buf_T *
  find_buffer(char_u *name, int err)
***************
*** 1081,1086 ****
--- 1082,1089 ----
      {
        buf = buflist_new(name == NULL || *name == NUL ? NULL : name,
                                               NULL, (linenr_T)0, BLN_LISTED);
+       if (buf == NULL)
+           return NULL;
        buf_copy_options(buf, BCO_ENTER);
        curbuf = buf;
  #ifdef FEAT_QUICKFIX
***************
*** 1187,1223 ****
  
      if ((opt->jo_set & JO_OUT_IO) && opt->jo_io[PART_OUT] == JIO_BUFFER)
      {
        /* writing output to a buffer. Default mode is NL. */
        if (!(opt->jo_set & JO_OUT_MODE))
            channel->ch_part[PART_OUT].ch_mode = MODE_NL;
        if (opt->jo_set & JO_OUT_BUF)
!           channel->ch_part[PART_OUT].ch_buffer =
!                                    buflist_findnr(opt->jo_io_buf[PART_OUT]);
        else
!           channel->ch_part[PART_OUT].ch_buffer =
!                               find_buffer(opt->jo_io_name[PART_OUT], FALSE);
!       ch_logs(channel, "writing out to buffer '%s'",
!                     (char *)channel->ch_part[PART_OUT].ch_buffer->b_ffname);
      }
  
      if ((opt->jo_set & JO_ERR_IO) && (opt->jo_io[PART_ERR] == JIO_BUFFER
         || (opt->jo_io[PART_ERR] == JIO_OUT && (opt->jo_set & JO_OUT_IO)
                                       && opt->jo_io[PART_OUT] == JIO_BUFFER)))
      {
        /* writing err to a buffer. Default mode is NL. */
        if (!(opt->jo_set & JO_ERR_MODE))
            channel->ch_part[PART_ERR].ch_mode = MODE_NL;
        if (opt->jo_io[PART_ERR] == JIO_OUT)
!           channel->ch_part[PART_ERR].ch_buffer =
!                                        channel->ch_part[PART_OUT].ch_buffer;
        else if (opt->jo_set & JO_ERR_BUF)
!           channel->ch_part[PART_ERR].ch_buffer =
!                                    buflist_findnr(opt->jo_io_buf[PART_ERR]);
        else
!           channel->ch_part[PART_ERR].ch_buffer =
!                                find_buffer(opt->jo_io_name[PART_ERR], TRUE);
!       ch_logs(channel, "writing err to buffer '%s'",
!                     (char *)channel->ch_part[PART_ERR].ch_buffer->b_ffname);
      }
  
      channel->ch_part[PART_OUT].ch_io = opt->jo_io[PART_OUT];
--- 1190,1243 ----
  
      if ((opt->jo_set & JO_OUT_IO) && opt->jo_io[PART_OUT] == JIO_BUFFER)
      {
+       buf_T *buf;
+ 
        /* writing output to a buffer. Default mode is NL. */
        if (!(opt->jo_set & JO_OUT_MODE))
            channel->ch_part[PART_OUT].ch_mode = MODE_NL;
        if (opt->jo_set & JO_OUT_BUF)
!       {
!           buf = buflist_findnr(opt->jo_io_buf[PART_OUT]);
!           if (buf == NULL)
!               EMSGN(_(e_nobufnr), (long)opt->jo_io_buf[PART_OUT]);
!       }
        else
!       {
!           buf = find_buffer(opt->jo_io_name[PART_OUT], FALSE);
!       }
!       if (buf != NULL)
!       {
!           ch_logs(channel, "writing out to buffer '%s'",
!                                                      (char *)buf->b_ffname);
!           channel->ch_part[PART_OUT].ch_buffer = buf;
!       }
      }
  
      if ((opt->jo_set & JO_ERR_IO) && (opt->jo_io[PART_ERR] == JIO_BUFFER
         || (opt->jo_io[PART_ERR] == JIO_OUT && (opt->jo_set & JO_OUT_IO)
                                       && opt->jo_io[PART_OUT] == JIO_BUFFER)))
      {
+       buf_T *buf;
+ 
        /* writing err to a buffer. Default mode is NL. */
        if (!(opt->jo_set & JO_ERR_MODE))
            channel->ch_part[PART_ERR].ch_mode = MODE_NL;
        if (opt->jo_io[PART_ERR] == JIO_OUT)
!           buf = channel->ch_part[PART_OUT].ch_buffer;
        else if (opt->jo_set & JO_ERR_BUF)
!       {
!           buf = buflist_findnr(opt->jo_io_buf[PART_ERR]);
!           if (buf == NULL)
!               EMSGN(_(e_nobufnr), (long)opt->jo_io_buf[PART_ERR]);
!       }
        else
!           buf = find_buffer(opt->jo_io_name[PART_ERR], TRUE);
!       if (buf != NULL)
!       {
!           ch_logs(channel, "writing err to buffer '%s'",
!                                                      (char *)buf->b_ffname);
!           channel->ch_part[PART_ERR].ch_buffer = buf;
!       }
      }
  
      channel->ch_part[PART_OUT].ch_io = opt->jo_io[PART_OUT];
***************
*** 1388,1393 ****
--- 1408,1432 ----
  }
  
  /*
+  * Handle buffer "buf" beeing freed, remove it from any channels.
+  */
+     void
+ channel_buffer_free(buf_T *buf)
+ {
+     channel_T *channel;
+     int               part;
+ 
+     for (channel = first_channel; channel != NULL; channel = channel->ch_next)
+       for (part = PART_SOCK; part <= PART_IN; ++part)
+       {
+           chanpart_T  *ch_part = &channel->ch_part[part];
+ 
+           if (ch_part->ch_buffer == buf)
+               ch_part->ch_buffer = NULL;
+       }
+ }
+ 
+ /*
   * Write any lines waiting to be written to a channel.
   */
      void
*** ../vim-7.4.1827/src/proto/channel.pro       2016-05-01 14:22:12.363965120 
+0200
--- src/proto/channel.pro       2016-05-09 20:34:44.922875135 +0200
***************
*** 14,19 ****
--- 14,20 ----
  void channel_set_job(channel_T *channel, job_T *job, jobopt_T *options);
  void channel_set_options(channel_T *channel, jobopt_T *opt);
  void channel_set_req_callback(channel_T *channel, int part, char_u *callback, 
partial_T *partial, int id);
+ void channel_buffer_free(buf_T *buf);
  void channel_write_any_lines(void);
  void channel_write_new_lines(buf_T *buf);
  char_u *channel_get(channel_T *channel, int part);
*** ../vim-7.4.1827/src/version.c       2016-05-09 17:57:59.814722474 +0200
--- src/version.c       2016-05-09 20:36:42.173545673 +0200
***************
*** 755,756 ****
--- 755,758 ----
  {   /* Add new patch number below this line */
+ /**/
+     1828,
  /**/

-- 
SOLDIER: What?  Ridden on a horse?
ARTHUR:  Yes!
SOLDIER: You're using coconuts!
                 "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
 \\\            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].
For more options, visit https://groups.google.com/d/optout.

Raspunde prin e-mail lui