forked from aniani/vim
patch 8.2.0442: channel contents might be used after being freed
Problem: Channel contents might be used after being freed. Solution: Reset the job channel before freeing the channel.
This commit is contained in:
@@ -396,6 +396,7 @@ channel_can_close(channel_T *channel)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Close a channel and free all its resources.
|
* Close a channel and free all its resources.
|
||||||
|
* The "channel" pointer remains valid.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
channel_free_contents(channel_T *channel)
|
channel_free_contents(channel_T *channel)
|
||||||
@@ -405,6 +406,9 @@ channel_free_contents(channel_T *channel)
|
|||||||
ch_log(channel, "Freeing channel");
|
ch_log(channel, "Freeing channel");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Unlink "channel" from the list of channels and free it.
|
||||||
|
*/
|
||||||
static void
|
static void
|
||||||
channel_free_channel(channel_T *channel)
|
channel_free_channel(channel_T *channel)
|
||||||
{
|
{
|
||||||
@@ -497,12 +501,10 @@ free_unused_channels(int copyID, int mask)
|
|||||||
ch_next = ch->ch_next;
|
ch_next = ch->ch_next;
|
||||||
if (!channel_still_useful(ch)
|
if (!channel_still_useful(ch)
|
||||||
&& (ch->ch_copyID & mask) != (copyID & mask))
|
&& (ch->ch_copyID & mask) != (copyID & mask))
|
||||||
{
|
|
||||||
// Free the channel struct itself.
|
// Free the channel struct itself.
|
||||||
channel_free_channel(ch);
|
channel_free_channel(ch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(FEAT_GUI) || defined(PROTO)
|
#if defined(FEAT_GUI) || defined(PROTO)
|
||||||
|
|
||||||
@@ -4453,16 +4455,13 @@ channel_parse_messages(void)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (channel->ch_to_be_freed || channel->ch_killing)
|
if (channel->ch_to_be_freed || channel->ch_killing)
|
||||||
{
|
|
||||||
if (channel->ch_killing)
|
|
||||||
{
|
{
|
||||||
channel_free_contents(channel);
|
channel_free_contents(channel);
|
||||||
channel_free_channel(channel);
|
if (channel->ch_job != NULL)
|
||||||
channel->ch_job->jv_channel = NULL;
|
channel->ch_job->jv_channel = NULL;
|
||||||
}
|
|
||||||
else
|
// free the channel and then start over
|
||||||
channel_free(channel);
|
channel_free_channel(channel);
|
||||||
// channel has been freed, start over
|
|
||||||
channel = first_channel;
|
channel = first_channel;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@@ -738,6 +738,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
442,
|
||||||
/**/
|
/**/
|
||||||
441,
|
441,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user