Patch 9.0.0990

3 views
Skip to first unread message

Bram Moolenaar

unread,
Dec 2, 2022, 10:59:25 AM12/2/22
to vim...@googlegroups.com

Patch 9.0.0990
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)
Files: src/evalvars.c, src/change.c, src/job.c, src/option.c,
src/popupwin.c, src/quickfix.c, src/time.c,
src/testdir/test_quickfix.vim


*** ../vim-9.0.0989/src/evalvars.c 2022-11-28 18:51:38.963571609 +0000
--- src/evalvars.c 2022-12-02 15:24:19.477669104 +0000
***************
*** 4792,4800 ****

/*
* 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.
*/
callback_T
get_callback(typval_T *arg)
--- 4792,4800 ----

/*
* Get a callback from "arg". It can be a Funcref or a function name.
! * 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,4808 ****
callback_T res;
int r = OK;

! res.cb_free_name = FALSE;
if (arg->v_type == VAR_PARTIAL && arg->vval.v_partial != NULL)
{
res.cb_partial = arg->vval.v_partial;
--- 4802,4808 ----
callback_T res;
int r = OK;

! CLEAR_FIELD(res);
if (arg->v_type == VAR_PARTIAL && arg->vval.v_partial != NULL)
{
res.cb_partial = arg->vval.v_partial;
***************
*** 4811,4835 ****
}
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)
{
if (arg->v_type == VAR_STRING)
{
! char_u *name;
!
! 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 = arg->vval.v_string;
func_ref(res.cb_name);
}
else if (arg->v_type == VAR_NUMBER && arg->vval.v_number == 0)
--- 4811,4831 ----
}
else
{
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 = get_scriptlocal_funcname(arg->vval.v_string);
if (name != NULL)
{
! res.cb_name = name;
! res.cb_free_name = TRUE;
}
}
func_ref(res.cb_name);
}
else if (arg->v_type == VAR_NUMBER && arg->vval.v_number == 0)
*** ../vim-9.0.0989/src/change.c 2022-11-02 13:30:37.530314524 +0000
--- src/change.c 2022-12-02 15:29:45.585756816 +0000
***************
*** 259,264 ****
--- 259,266 ----
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;
*** ../vim-9.0.0989/src/job.c 2022-06-19 13:07:36.000000000 +0100
--- src/job.c 2022-12-02 15:48:00.718449900 +0000
***************
*** 74,105 ****
CLEAR_POINTER(opt);
}

/*
* 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);
if (opt->jo_env != NULL)
dict_unref(opt->jo_env);
}
--- 74,104 ----
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)
{
! 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,1692 ****
--- 1686,1693 ----

free_callback(&buf->b_prompt_callback);
set_callback(&buf->b_prompt_callback, &callback);
+ if (callback.cb_free_name)
+ vim_free(callback.cb_name);
}

/*
***************
*** 1714,1719 ****
--- 1715,1722 ----

free_callback(&buf->b_prompt_interrupt);
set_callback(&buf->b_prompt_interrupt, &callback);
+ if (callback.cb_free_name)
+ vim_free(callback.cb_name);
}


*** ../vim-9.0.0989/src/option.c 2022-11-28 11:36:46.295659899 +0000
--- src/option.c 2022-12-02 15:41:12.994213830 +0000
***************
*** 7370,7375 ****
--- 7370,7377 ----

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
*** ../vim-9.0.0989/src/popupwin.c 2022-10-14 20:09:00.895207512 +0100
--- src/popupwin.c 2022-12-02 15:44:28.446338356 +0000
***************
*** 444,450 ****
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);
clear_tv(&tv);
}
}
--- 444,456 ----
if (get_lambda_tv_and_compile(&ptr, &tv, FALSE, &EVALARG_EVALUATE) == OK)
{
wp->w_popup_timer = create_timer(time, 0);
! 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,966 ****
--- 967,974 ----
{
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,995 ****
--- 998,1005 ----
{
free_callback(&wp->w_close_cb);
set_callback(&wp->w_close_cb, &callback);
+ if (callback.cb_free_name)
+ vim_free(callback.cb_name);
}
}
}
***************
*** 2229,2235 ****
--- 2239,2249 ----
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;
*** ../vim-9.0.0989/src/quickfix.c 2022-11-28 20:34:47.704140309 +0000
--- src/quickfix.c 2022-12-02 15:43:06.150288994 +0000
***************
*** 7633,7639 ****
--- 7633,7643 ----
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;
}
*** ../vim-9.0.0989/src/time.c 2022-11-30 18:11:52.694904295 +0000
--- src/time.c 2022-12-02 15:39:27.422134506 +0000
***************
*** 908,913 ****
--- 908,915 ----
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;
}
}
*** ../vim-9.0.0989/src/testdir/test_quickfix.vim 2022-11-28 11:36:46.299659897 +0000
--- src/testdir/test_quickfix.vim 2022-12-02 15:26:46.093712365 +0000
***************
*** 6387,6391 ****
--- 6387,6403 ----
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
*** ../vim-9.0.0989/src/version.c 2022-12-02 15:06:03.740761560 +0000
--- src/version.c 2022-12-02 15:16:34.777460477 +0000
***************
*** 697,698 ****
--- 697,700 ----
{ /* Add new patch number below this line */
+ /**/
+ 990,
/**/

--
hundred-and-one symptoms of being an internet addict:
206. You religiously respond immediately to e-mail, while ignoring
your growing pile of snail mail.

/// Bram Moolenaar -- Br...@Moolenaar.net -- http://www.Moolenaar.net \\\
/// \\\
\\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
Reply all
Reply to author
Forward
0 new messages