To: vim_dev@googlegroups.com Subject: Patch 9.0.0990 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ 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 -- Bram@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 ///