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.