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;
|
||||
|
||||
set_callback(&lnr->lr_callback, &callback);
|
||||
if (callback.cb_free_name)
|
||||
vim_free(callback.cb_name);
|
||||
|
||||
lnr->lr_id = ++next_listener_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.
|
||||
* When "arg" is zero return an empty string.
|
||||
* "cb_name" is not allocated.
|
||||
* "cb_name" is set to NULL for an invalid argument.
|
||||
* When "arg" is zero "res.cb_name" is set to an empty string.
|
||||
* If "res.cb_name" is allocated then "res.cb_free_name" is set to TRUE.
|
||||
* "res.cb_name" is set to NULL for an invalid argument.
|
||||
*/
|
||||
callback_T
|
||||
get_callback(typval_T *arg)
|
||||
@ -4802,7 +4802,7 @@ get_callback(typval_T *arg)
|
||||
callback_T res;
|
||||
int r = OK;
|
||||
|
||||
res.cb_free_name = FALSE;
|
||||
CLEAR_FIELD(res);
|
||||
if (arg->v_type == VAR_PARTIAL && arg->vval.v_partial != NULL)
|
||||
{
|
||||
res.cb_partial = arg->vval.v_partial;
|
||||
@ -4811,25 +4811,21 @@ get_callback(typval_T *arg)
|
||||
}
|
||||
else
|
||||
{
|
||||
res.cb_partial = NULL;
|
||||
if (arg->v_type == VAR_STRING && arg->vval.v_string != NULL
|
||||
&& isdigit(*arg->vval.v_string))
|
||||
r = FAIL;
|
||||
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)
|
||||
{
|
||||
char_u *name;
|
||||
|
||||
name = get_scriptlocal_funcname(arg->vval.v_string);
|
||||
char_u *name = get_scriptlocal_funcname(arg->vval.v_string);
|
||||
if (name != NULL)
|
||||
{
|
||||
vim_free(arg->vval.v_string);
|
||||
arg->vval.v_string = name;
|
||||
res.cb_name = name;
|
||||
res.cb_free_name = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
res.cb_name = arg->vval.v_string;
|
||||
func_ref(res.cb_name);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
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.
|
||||
*/
|
||||
void
|
||||
free_job_options(jobopt_T *opt)
|
||||
{
|
||||
if (opt->jo_callback.cb_partial != NULL)
|
||||
partial_unref(opt->jo_callback.cb_partial);
|
||||
else if (opt->jo_callback.cb_name != NULL)
|
||||
func_unref(opt->jo_callback.cb_name);
|
||||
if (opt->jo_out_cb.cb_partial != NULL)
|
||||
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);
|
||||
unref_job_callback(&opt->jo_callback);
|
||||
unref_job_callback(&opt->jo_out_cb);
|
||||
unref_job_callback(&opt->jo_err_cb);
|
||||
unref_job_callback(&opt->jo_close_cb);
|
||||
unref_job_callback(&opt->jo_exit_cb);
|
||||
|
||||
if (opt->jo_env != NULL)
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
set_callback(optcb, &cb);
|
||||
if (cb.cb_free_name)
|
||||
vim_free(cb.cb_name);
|
||||
free_tv(tv);
|
||||
|
||||
// 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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
@ -961,6 +967,8 @@ apply_general_options(win_T *wp, dict_T *dict)
|
||||
{
|
||||
free_callback(&wp->w_filter_cb);
|
||||
set_callback(&wp->w_filter_cb, &callback);
|
||||
if (callback.cb_free_name)
|
||||
vim_free(callback.cb_name);
|
||||
}
|
||||
}
|
||||
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);
|
||||
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";
|
||||
callback = get_callback(&tv);
|
||||
if (callback.cb_name != NULL)
|
||||
{
|
||||
set_callback(&wp->w_filter_cb, &callback);
|
||||
if (callback.cb_free_name)
|
||||
vim_free(callback.cb_name);
|
||||
}
|
||||
|
||||
wp->w_p_wrap = 0;
|
||||
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);
|
||||
cb = get_callback(&di->di_tv);
|
||||
if (cb.cb_name != NULL && *cb.cb_name != NUL)
|
||||
{
|
||||
set_callback(&qfl->qf_qftf_cb, &cb);
|
||||
if (cb.cb_free_name)
|
||||
vim_free(cb.cb_name);
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
@ -6387,5 +6387,17 @@ func Test_info_line_with_space()
|
||||
call setqflist([], 'f')
|
||||
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
|
||||
|
@ -908,6 +908,8 @@ f_timer_start(typval_T *argvars, typval_T *rettv)
|
||||
else
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -695,6 +695,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
990,
|
||||
/**/
|
||||
989,
|
||||
/**/
|
||||
|
Loading…
x
Reference in New Issue
Block a user