mirror of
https://github.com/vim/vim.git
synced 2025-07-26 11:04:33 -04:00
patch 9.0.0990: callback name argument is changed by setqflist()
Problem: Callback name argument is changed by setqflist(). Solution: Use the expanded function name for the callback, do not store it in the argument. (closes #11653)
This commit is contained in:
parent
9c8d12c811
commit
c96b7f5d2a
@ -259,6 +259,8 @@ f_listener_add(typval_T *argvars, typval_T *rettv)
|
|||||||
buf->b_listener = lnr;
|
buf->b_listener = lnr;
|
||||||
|
|
||||||
set_callback(&lnr->lr_callback, &callback);
|
set_callback(&lnr->lr_callback, &callback);
|
||||||
|
if (callback.cb_free_name)
|
||||||
|
vim_free(callback.cb_name);
|
||||||
|
|
||||||
lnr->lr_id = ++next_listener_id;
|
lnr->lr_id = ++next_listener_id;
|
||||||
rettv->vval.v_number = lnr->lr_id;
|
rettv->vval.v_number = lnr->lr_id;
|
||||||
|
@ -4792,9 +4792,9 @@ f_setbufvar(typval_T *argvars, typval_T *rettv UNUSED)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Get a callback from "arg". It can be a Funcref or a function name.
|
* Get a callback from "arg". It can be a Funcref or a function name.
|
||||||
* When "arg" is zero return an empty string.
|
* When "arg" is zero "res.cb_name" is set to an empty string.
|
||||||
* "cb_name" is not allocated.
|
* If "res.cb_name" is allocated then "res.cb_free_name" is set to TRUE.
|
||||||
* "cb_name" is set to NULL for an invalid argument.
|
* "res.cb_name" is set to NULL for an invalid argument.
|
||||||
*/
|
*/
|
||||||
callback_T
|
callback_T
|
||||||
get_callback(typval_T *arg)
|
get_callback(typval_T *arg)
|
||||||
@ -4802,7 +4802,7 @@ get_callback(typval_T *arg)
|
|||||||
callback_T res;
|
callback_T res;
|
||||||
int r = OK;
|
int r = OK;
|
||||||
|
|
||||||
res.cb_free_name = FALSE;
|
CLEAR_FIELD(res);
|
||||||
if (arg->v_type == VAR_PARTIAL && arg->vval.v_partial != NULL)
|
if (arg->v_type == VAR_PARTIAL && arg->vval.v_partial != NULL)
|
||||||
{
|
{
|
||||||
res.cb_partial = arg->vval.v_partial;
|
res.cb_partial = arg->vval.v_partial;
|
||||||
@ -4811,25 +4811,21 @@ get_callback(typval_T *arg)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
res.cb_partial = NULL;
|
|
||||||
if (arg->v_type == VAR_STRING && arg->vval.v_string != NULL
|
if (arg->v_type == VAR_STRING && arg->vval.v_string != NULL
|
||||||
&& isdigit(*arg->vval.v_string))
|
&& isdigit(*arg->vval.v_string))
|
||||||
r = FAIL;
|
r = FAIL;
|
||||||
else if (arg->v_type == VAR_FUNC || arg->v_type == VAR_STRING)
|
else if (arg->v_type == VAR_FUNC || arg->v_type == VAR_STRING)
|
||||||
{
|
{
|
||||||
|
res.cb_name = arg->vval.v_string;
|
||||||
if (arg->v_type == VAR_STRING)
|
if (arg->v_type == VAR_STRING)
|
||||||
{
|
{
|
||||||
char_u *name;
|
char_u *name = get_scriptlocal_funcname(arg->vval.v_string);
|
||||||
|
|
||||||
name = get_scriptlocal_funcname(arg->vval.v_string);
|
|
||||||
if (name != NULL)
|
if (name != NULL)
|
||||||
{
|
{
|
||||||
vim_free(arg->vval.v_string);
|
res.cb_name = name;
|
||||||
arg->vval.v_string = name;
|
res.cb_free_name = TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
res.cb_name = arg->vval.v_string;
|
|
||||||
func_ref(res.cb_name);
|
func_ref(res.cb_name);
|
||||||
}
|
}
|
||||||
else if (arg->v_type == VAR_NUMBER && arg->vval.v_number == 0)
|
else if (arg->v_type == VAR_NUMBER && arg->vval.v_number == 0)
|
||||||
|
43
src/job.c
43
src/job.c
@ -74,32 +74,31 @@ clear_job_options(jobopt_T *opt)
|
|||||||
CLEAR_POINTER(opt);
|
CLEAR_POINTER(opt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
unref_job_callback(callback_T *cb)
|
||||||
|
{
|
||||||
|
if (cb->cb_partial != NULL)
|
||||||
|
partial_unref(cb->cb_partial);
|
||||||
|
else if (cb->cb_name != NULL)
|
||||||
|
{
|
||||||
|
func_unref(cb->cb_name);
|
||||||
|
if (cb->cb_free_name)
|
||||||
|
vim_free(cb->cb_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Free any members of a jobopt_T.
|
* Free any members of a jobopt_T.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
free_job_options(jobopt_T *opt)
|
free_job_options(jobopt_T *opt)
|
||||||
{
|
{
|
||||||
if (opt->jo_callback.cb_partial != NULL)
|
unref_job_callback(&opt->jo_callback);
|
||||||
partial_unref(opt->jo_callback.cb_partial);
|
unref_job_callback(&opt->jo_out_cb);
|
||||||
else if (opt->jo_callback.cb_name != NULL)
|
unref_job_callback(&opt->jo_err_cb);
|
||||||
func_unref(opt->jo_callback.cb_name);
|
unref_job_callback(&opt->jo_close_cb);
|
||||||
if (opt->jo_out_cb.cb_partial != NULL)
|
unref_job_callback(&opt->jo_exit_cb);
|
||||||
partial_unref(opt->jo_out_cb.cb_partial);
|
|
||||||
else if (opt->jo_out_cb.cb_name != NULL)
|
|
||||||
func_unref(opt->jo_out_cb.cb_name);
|
|
||||||
if (opt->jo_err_cb.cb_partial != NULL)
|
|
||||||
partial_unref(opt->jo_err_cb.cb_partial);
|
|
||||||
else if (opt->jo_err_cb.cb_name != NULL)
|
|
||||||
func_unref(opt->jo_err_cb.cb_name);
|
|
||||||
if (opt->jo_close_cb.cb_partial != NULL)
|
|
||||||
partial_unref(opt->jo_close_cb.cb_partial);
|
|
||||||
else if (opt->jo_close_cb.cb_name != NULL)
|
|
||||||
func_unref(opt->jo_close_cb.cb_name);
|
|
||||||
if (opt->jo_exit_cb.cb_partial != NULL)
|
|
||||||
partial_unref(opt->jo_exit_cb.cb_partial);
|
|
||||||
else if (opt->jo_exit_cb.cb_name != NULL)
|
|
||||||
func_unref(opt->jo_exit_cb.cb_name);
|
|
||||||
if (opt->jo_env != NULL)
|
if (opt->jo_env != NULL)
|
||||||
dict_unref(opt->jo_env);
|
dict_unref(opt->jo_env);
|
||||||
}
|
}
|
||||||
@ -1687,6 +1686,8 @@ f_prompt_setcallback(typval_T *argvars, typval_T *rettv UNUSED)
|
|||||||
|
|
||||||
free_callback(&buf->b_prompt_callback);
|
free_callback(&buf->b_prompt_callback);
|
||||||
set_callback(&buf->b_prompt_callback, &callback);
|
set_callback(&buf->b_prompt_callback, &callback);
|
||||||
|
if (callback.cb_free_name)
|
||||||
|
vim_free(callback.cb_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1714,6 +1715,8 @@ f_prompt_setinterrupt(typval_T *argvars, typval_T *rettv UNUSED)
|
|||||||
|
|
||||||
free_callback(&buf->b_prompt_interrupt);
|
free_callback(&buf->b_prompt_interrupt);
|
||||||
set_callback(&buf->b_prompt_interrupt, &callback);
|
set_callback(&buf->b_prompt_interrupt, &callback);
|
||||||
|
if (callback.cb_free_name)
|
||||||
|
vim_free(callback.cb_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -7370,6 +7370,8 @@ option_set_callback_func(char_u *optval UNUSED, callback_T *optcb UNUSED)
|
|||||||
|
|
||||||
free_callback(optcb);
|
free_callback(optcb);
|
||||||
set_callback(optcb, &cb);
|
set_callback(optcb, &cb);
|
||||||
|
if (cb.cb_free_name)
|
||||||
|
vim_free(cb.cb_name);
|
||||||
free_tv(tv);
|
free_tv(tv);
|
||||||
|
|
||||||
// when using Vim9 style "import.funcname" it needs to be expanded to
|
// when using Vim9 style "import.funcname" it needs to be expanded to
|
||||||
|
@ -444,7 +444,13 @@ popup_add_timeout(win_T *wp, int time, int close)
|
|||||||
if (get_lambda_tv_and_compile(&ptr, &tv, FALSE, &EVALARG_EVALUATE) == OK)
|
if (get_lambda_tv_and_compile(&ptr, &tv, FALSE, &EVALARG_EVALUATE) == OK)
|
||||||
{
|
{
|
||||||
wp->w_popup_timer = create_timer(time, 0);
|
wp->w_popup_timer = create_timer(time, 0);
|
||||||
wp->w_popup_timer->tr_callback = get_callback(&tv);
|
callback_T cb = get_callback(&tv);
|
||||||
|
if (cb.cb_name != NULL && !cb.cb_free_name)
|
||||||
|
{
|
||||||
|
cb.cb_name = vim_strsave(cb.cb_name);
|
||||||
|
cb.cb_free_name = TRUE;
|
||||||
|
}
|
||||||
|
wp->w_popup_timer->tr_callback = cb;
|
||||||
clear_tv(&tv);
|
clear_tv(&tv);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -961,6 +967,8 @@ apply_general_options(win_T *wp, dict_T *dict)
|
|||||||
{
|
{
|
||||||
free_callback(&wp->w_filter_cb);
|
free_callback(&wp->w_filter_cb);
|
||||||
set_callback(&wp->w_filter_cb, &callback);
|
set_callback(&wp->w_filter_cb, &callback);
|
||||||
|
if (callback.cb_free_name)
|
||||||
|
vim_free(callback.cb_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
nr = dict_get_bool(dict, "mapping", -1);
|
nr = dict_get_bool(dict, "mapping", -1);
|
||||||
@ -990,6 +998,8 @@ apply_general_options(win_T *wp, dict_T *dict)
|
|||||||
{
|
{
|
||||||
free_callback(&wp->w_close_cb);
|
free_callback(&wp->w_close_cb);
|
||||||
set_callback(&wp->w_close_cb, &callback);
|
set_callback(&wp->w_close_cb, &callback);
|
||||||
|
if (callback.cb_free_name)
|
||||||
|
vim_free(callback.cb_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2229,7 +2239,11 @@ popup_create(typval_T *argvars, typval_T *rettv, create_type_T type)
|
|||||||
tv.vval.v_string = (char_u *)"popup_filter_menu";
|
tv.vval.v_string = (char_u *)"popup_filter_menu";
|
||||||
callback = get_callback(&tv);
|
callback = get_callback(&tv);
|
||||||
if (callback.cb_name != NULL)
|
if (callback.cb_name != NULL)
|
||||||
|
{
|
||||||
set_callback(&wp->w_filter_cb, &callback);
|
set_callback(&wp->w_filter_cb, &callback);
|
||||||
|
if (callback.cb_free_name)
|
||||||
|
vim_free(callback.cb_name);
|
||||||
|
}
|
||||||
|
|
||||||
wp->w_p_wrap = 0;
|
wp->w_p_wrap = 0;
|
||||||
wp->w_popup_flags |= POPF_CURSORLINE;
|
wp->w_popup_flags |= POPF_CURSORLINE;
|
||||||
|
@ -7633,7 +7633,11 @@ qf_setprop_qftf(qf_info_T *qi UNUSED, qf_list_T *qfl, dictitem_T *di)
|
|||||||
free_callback(&qfl->qf_qftf_cb);
|
free_callback(&qfl->qf_qftf_cb);
|
||||||
cb = get_callback(&di->di_tv);
|
cb = get_callback(&di->di_tv);
|
||||||
if (cb.cb_name != NULL && *cb.cb_name != NUL)
|
if (cb.cb_name != NULL && *cb.cb_name != NUL)
|
||||||
|
{
|
||||||
set_callback(&qfl->qf_qftf_cb, &cb);
|
set_callback(&qfl->qf_qftf_cb, &cb);
|
||||||
|
if (cb.cb_free_name)
|
||||||
|
vim_free(cb.cb_name);
|
||||||
|
}
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
@ -6387,5 +6387,17 @@ func Test_info_line_with_space()
|
|||||||
call setqflist([], 'f')
|
call setqflist([], 'f')
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
func s:QfTf(_)
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func Test_setqflist_cb_arg()
|
||||||
|
" This was changing the callback name in the dictionary.
|
||||||
|
let d = #{quickfixtextfunc: 's:QfTf'}
|
||||||
|
call setqflist([], 'a', d)
|
||||||
|
call assert_equal('s:QfTf', d.quickfixtextfunc)
|
||||||
|
|
||||||
|
call setqflist([], 'f')
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
|
||||||
" vim: shiftwidth=2 sts=2 expandtab
|
" vim: shiftwidth=2 sts=2 expandtab
|
||||||
|
@ -908,6 +908,8 @@ f_timer_start(typval_T *argvars, typval_T *rettv)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
set_callback(&timer->tr_callback, &callback);
|
set_callback(&timer->tr_callback, &callback);
|
||||||
|
if (callback.cb_free_name)
|
||||||
|
vim_free(callback.cb_name);
|
||||||
rettv->vval.v_number = (varnumber_T)timer->tr_id;
|
rettv->vval.v_number = (varnumber_T)timer->tr_id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -695,6 +695,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 */
|
||||||
|
/**/
|
||||||
|
990,
|
||||||
/**/
|
/**/
|
||||||
989,
|
989,
|
||||||
/**/
|
/**/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user