mirror of
https://github.com/vim/vim.git
synced 2025-11-16 23:24:03 -05:00
patch 7.4.2026
Problem: Reference counting for callbacks isn't right. Solution: Add free_callback(). (Ken Takata) Fix reference count.
This commit is contained in:
106
src/channel.c
106
src/channel.c
@@ -1113,6 +1113,23 @@ find_buffer(char_u *name, int err)
|
|||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
set_callback(
|
||||||
|
char_u **cbp,
|
||||||
|
partial_T **pp,
|
||||||
|
char_u *callback,
|
||||||
|
partial_T *partial)
|
||||||
|
{
|
||||||
|
free_callback(*cbp, *pp);
|
||||||
|
if (callback != NULL && *callback != NUL)
|
||||||
|
*cbp = vim_strsave(callback);
|
||||||
|
else
|
||||||
|
*cbp = NULL;
|
||||||
|
*pp = partial;
|
||||||
|
if (*pp != NULL)
|
||||||
|
++(*pp)->pt_refcount;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set various properties from an "opt" argument.
|
* Set various properties from an "opt" argument.
|
||||||
*/
|
*/
|
||||||
@@ -1120,8 +1137,6 @@ find_buffer(char_u *name, int err)
|
|||||||
channel_set_options(channel_T *channel, jobopt_T *opt)
|
channel_set_options(channel_T *channel, jobopt_T *opt)
|
||||||
{
|
{
|
||||||
int part;
|
int part;
|
||||||
char_u **cbp;
|
|
||||||
partial_T **pp;
|
|
||||||
|
|
||||||
if (opt->jo_set & JO_MODE)
|
if (opt->jo_set & JO_MODE)
|
||||||
for (part = PART_SOCK; part <= PART_IN; ++part)
|
for (part = PART_SOCK; part <= PART_IN; ++part)
|
||||||
@@ -1144,61 +1159,19 @@ channel_set_options(channel_T *channel, jobopt_T *opt)
|
|||||||
channel->ch_part[PART_IN].ch_block_write = 1;
|
channel->ch_part[PART_IN].ch_block_write = 1;
|
||||||
|
|
||||||
if (opt->jo_set & JO_CALLBACK)
|
if (opt->jo_set & JO_CALLBACK)
|
||||||
{
|
set_callback(&channel->ch_callback, &channel->ch_partial,
|
||||||
cbp = &channel->ch_callback;
|
opt->jo_callback, opt->jo_partial);
|
||||||
pp = &channel->ch_partial;
|
|
||||||
vim_free(*cbp);
|
|
||||||
partial_unref(*pp);
|
|
||||||
if (opt->jo_callback != NULL && *opt->jo_callback != NUL)
|
|
||||||
*cbp = vim_strsave(opt->jo_callback);
|
|
||||||
else
|
|
||||||
*cbp = NULL;
|
|
||||||
*pp = opt->jo_partial;
|
|
||||||
if (*pp != NULL)
|
|
||||||
++(*pp)->pt_refcount;
|
|
||||||
}
|
|
||||||
if (opt->jo_set & JO_OUT_CALLBACK)
|
if (opt->jo_set & JO_OUT_CALLBACK)
|
||||||
{
|
set_callback(&channel->ch_part[PART_OUT].ch_callback,
|
||||||
cbp = &channel->ch_part[PART_OUT].ch_callback;
|
&channel->ch_part[PART_OUT].ch_partial,
|
||||||
pp = &channel->ch_part[PART_OUT].ch_partial;
|
opt->jo_out_cb, opt->jo_out_partial);
|
||||||
vim_free(*cbp);
|
|
||||||
partial_unref(*pp);
|
|
||||||
if (opt->jo_out_cb != NULL && *opt->jo_out_cb != NUL)
|
|
||||||
*cbp = vim_strsave(opt->jo_out_cb);
|
|
||||||
else
|
|
||||||
*cbp = NULL;
|
|
||||||
*pp = opt->jo_out_partial;
|
|
||||||
if (*pp != NULL)
|
|
||||||
++(*pp)->pt_refcount;
|
|
||||||
}
|
|
||||||
if (opt->jo_set & JO_ERR_CALLBACK)
|
if (opt->jo_set & JO_ERR_CALLBACK)
|
||||||
{
|
set_callback(&channel->ch_part[PART_ERR].ch_callback,
|
||||||
cbp = &channel->ch_part[PART_ERR].ch_callback;
|
&channel->ch_part[PART_ERR].ch_partial,
|
||||||
pp = &channel->ch_part[PART_ERR].ch_partial;
|
opt->jo_err_cb, opt->jo_err_partial);
|
||||||
vim_free(*cbp);
|
|
||||||
partial_unref(*pp);
|
|
||||||
if (opt->jo_err_cb != NULL && *opt->jo_err_cb != NUL)
|
|
||||||
*cbp = vim_strsave(opt->jo_err_cb);
|
|
||||||
else
|
|
||||||
*cbp = NULL;
|
|
||||||
*pp = opt->jo_err_partial;
|
|
||||||
if (*pp != NULL)
|
|
||||||
++(*pp)->pt_refcount;
|
|
||||||
}
|
|
||||||
if (opt->jo_set & JO_CLOSE_CALLBACK)
|
if (opt->jo_set & JO_CLOSE_CALLBACK)
|
||||||
{
|
set_callback(&channel->ch_close_cb, &channel->ch_close_partial,
|
||||||
cbp = &channel->ch_close_cb;
|
opt->jo_close_cb, opt->jo_close_partial);
|
||||||
pp = &channel->ch_close_partial;
|
|
||||||
vim_free(*cbp);
|
|
||||||
partial_unref(*pp);
|
|
||||||
if (opt->jo_close_cb != NULL && *opt->jo_close_cb != NUL)
|
|
||||||
*cbp = vim_strsave(opt->jo_close_cb);
|
|
||||||
else
|
|
||||||
*cbp = NULL;
|
|
||||||
*pp = opt->jo_close_partial;
|
|
||||||
if (*pp != NULL)
|
|
||||||
++(*pp)->pt_refcount;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((opt->jo_set & JO_OUT_IO) && opt->jo_io[PART_OUT] == JIO_BUFFER)
|
if ((opt->jo_set & JO_OUT_IO) && opt->jo_io[PART_OUT] == JIO_BUFFER)
|
||||||
{
|
{
|
||||||
@@ -2228,8 +2201,7 @@ invoke_one_time_callback(
|
|||||||
* invokes ch_close() the list will be cleared. */
|
* invokes ch_close() the list will be cleared. */
|
||||||
remove_cb_node(cbhead, item);
|
remove_cb_node(cbhead, item);
|
||||||
invoke_callback(channel, item->cq_callback, item->cq_partial, argv);
|
invoke_callback(channel, item->cq_callback, item->cq_partial, argv);
|
||||||
vim_free(item->cq_callback);
|
free_callback(item->cq_callback, item->cq_partial);
|
||||||
partial_unref(item->cq_partial);
|
|
||||||
vim_free(item);
|
vim_free(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2725,9 +2697,8 @@ channel_close(channel_T *channel, int invoke_close_cb)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* the callback is only called once */
|
/* the callback is only called once */
|
||||||
vim_free(channel->ch_close_cb);
|
free_callback(channel->ch_close_cb, channel->ch_close_partial);
|
||||||
channel->ch_close_cb = NULL;
|
channel->ch_close_cb = NULL;
|
||||||
partial_unref(channel->ch_close_partial);
|
|
||||||
channel->ch_close_partial = NULL;
|
channel->ch_close_partial = NULL;
|
||||||
|
|
||||||
--channel->ch_refcount;
|
--channel->ch_refcount;
|
||||||
@@ -2763,8 +2734,7 @@ channel_clear_one(channel_T *channel, int part)
|
|||||||
cbq_T *node = cb_head->cq_next;
|
cbq_T *node = cb_head->cq_next;
|
||||||
|
|
||||||
remove_cb_node(cb_head, node);
|
remove_cb_node(cb_head, node);
|
||||||
vim_free(node->cq_callback);
|
free_callback(node->cq_callback, node->cq_partial);
|
||||||
partial_unref(node->cq_partial);
|
|
||||||
vim_free(node);
|
vim_free(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2774,9 +2744,9 @@ channel_clear_one(channel_T *channel, int part)
|
|||||||
remove_json_node(json_head, json_head->jq_next);
|
remove_json_node(json_head, json_head->jq_next);
|
||||||
}
|
}
|
||||||
|
|
||||||
vim_free(channel->ch_part[part].ch_callback);
|
free_callback(channel->ch_part[part].ch_callback,
|
||||||
|
channel->ch_part[part].ch_partial);
|
||||||
channel->ch_part[part].ch_callback = NULL;
|
channel->ch_part[part].ch_callback = NULL;
|
||||||
partial_unref(channel->ch_part[part].ch_partial);
|
|
||||||
channel->ch_part[part].ch_partial = NULL;
|
channel->ch_part[part].ch_partial = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2793,13 +2763,11 @@ channel_clear(channel_T *channel)
|
|||||||
channel_clear_one(channel, PART_OUT);
|
channel_clear_one(channel, PART_OUT);
|
||||||
channel_clear_one(channel, PART_ERR);
|
channel_clear_one(channel, PART_ERR);
|
||||||
/* there is no callback or queue for PART_IN */
|
/* there is no callback or queue for PART_IN */
|
||||||
vim_free(channel->ch_callback);
|
free_callback(channel->ch_callback, channel->ch_partial);
|
||||||
channel->ch_callback = NULL;
|
channel->ch_callback = NULL;
|
||||||
partial_unref(channel->ch_partial);
|
|
||||||
channel->ch_partial = NULL;
|
channel->ch_partial = NULL;
|
||||||
vim_free(channel->ch_close_cb);
|
free_callback(channel->ch_close_cb, channel->ch_close_partial);
|
||||||
channel->ch_close_cb = NULL;
|
channel->ch_close_cb = NULL;
|
||||||
partial_unref(channel->ch_close_partial);
|
|
||||||
channel->ch_close_partial = NULL;
|
channel->ch_close_partial = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4319,8 +4287,7 @@ job_free_contents(job_T *job)
|
|||||||
mch_clear_job(job);
|
mch_clear_job(job);
|
||||||
|
|
||||||
vim_free(job->jv_stoponexit);
|
vim_free(job->jv_stoponexit);
|
||||||
vim_free(job->jv_exit_cb);
|
free_callback(job->jv_exit_cb, job->jv_exit_partial);
|
||||||
partial_unref(job->jv_exit_partial);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -4485,8 +4452,7 @@ job_set_options(job_T *job, jobopt_T *opt)
|
|||||||
}
|
}
|
||||||
if (opt->jo_set & JO_EXIT_CB)
|
if (opt->jo_set & JO_EXIT_CB)
|
||||||
{
|
{
|
||||||
vim_free(job->jv_exit_cb);
|
free_callback(job->jv_exit_cb, job->jv_exit_partial);
|
||||||
partial_unref(job->jv_exit_partial);
|
|
||||||
if (opt->jo_exit_cb == NULL || *opt->jo_exit_cb == NUL)
|
if (opt->jo_exit_cb == NULL || *opt->jo_exit_cb == NUL)
|
||||||
{
|
{
|
||||||
job->jv_exit_cb = NULL;
|
job->jv_exit_cb = NULL;
|
||||||
|
|||||||
22
src/eval.c
22
src/eval.c
@@ -21178,13 +21178,33 @@ get_callback(typval_T *arg, partial_T **pp)
|
|||||||
return (*pp)->pt_name;
|
return (*pp)->pt_name;
|
||||||
}
|
}
|
||||||
*pp = NULL;
|
*pp = NULL;
|
||||||
if (arg->v_type == VAR_FUNC || arg->v_type == VAR_STRING)
|
if (arg->v_type == VAR_FUNC)
|
||||||
|
{
|
||||||
|
func_ref(arg->vval.v_string);
|
||||||
|
return arg->vval.v_string;
|
||||||
|
}
|
||||||
|
if (arg->v_type == VAR_STRING)
|
||||||
return arg->vval.v_string;
|
return arg->vval.v_string;
|
||||||
if (arg->v_type == VAR_NUMBER && arg->vval.v_number == 0)
|
if (arg->v_type == VAR_NUMBER && arg->vval.v_number == 0)
|
||||||
return (char_u *)"";
|
return (char_u *)"";
|
||||||
EMSG(_("E921: Invalid callback argument"));
|
EMSG(_("E921: Invalid callback argument"));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Unref/free "callback" and "partial" retured by get_callback().
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
free_callback(char_u *callback, partial_T *partial)
|
||||||
|
{
|
||||||
|
if (partial != NULL)
|
||||||
|
partial_unref(partial);
|
||||||
|
else if (callback != NULL)
|
||||||
|
{
|
||||||
|
func_unref(callback);
|
||||||
|
vim_free(callback);
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef FEAT_TIMERS
|
#ifdef FEAT_TIMERS
|
||||||
|
|||||||
@@ -1121,8 +1121,7 @@ remove_timer(timer_T *timer)
|
|||||||
static void
|
static void
|
||||||
free_timer(timer_T *timer)
|
free_timer(timer_T *timer)
|
||||||
{
|
{
|
||||||
vim_free(timer->tr_callback);
|
free_callback(timer->tr_callback, timer->tr_partial);
|
||||||
partial_unref(timer->tr_partial);
|
|
||||||
vim_free(timer);
|
vim_free(timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -94,6 +94,7 @@ void mzscheme_call_vim(char_u *name, typval_T *args, typval_T *rettv);
|
|||||||
float_T vim_round(float_T f);
|
float_T vim_round(float_T f);
|
||||||
long do_searchpair(char_u *spat, char_u *mpat, char_u *epat, int dir, char_u *skip, int flags, pos_T *match_pos, linenr_T lnum_stop, long time_limit);
|
long do_searchpair(char_u *spat, char_u *mpat, char_u *epat, int dir, char_u *skip, int flags, pos_T *match_pos, linenr_T lnum_stop, long time_limit);
|
||||||
char_u *get_callback(typval_T *arg, partial_T **pp);
|
char_u *get_callback(typval_T *arg, partial_T **pp);
|
||||||
|
void free_callback(char_u *callback, partial_T *partial);
|
||||||
void set_vim_var_nr(int idx, varnumber_T val);
|
void set_vim_var_nr(int idx, varnumber_T val);
|
||||||
varnumber_T get_vim_var_nr(int idx);
|
varnumber_T get_vim_var_nr(int idx);
|
||||||
char_u *get_vim_var_str(int idx);
|
char_u *get_vim_var_str(int idx);
|
||||||
|
|||||||
@@ -758,6 +758,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 */
|
||||||
|
/**/
|
||||||
|
2026,
|
||||||
/**/
|
/**/
|
||||||
2025,
|
2025,
|
||||||
/**/
|
/**/
|
||||||
|
|||||||
Reference in New Issue
Block a user