From 4490ec4e839e45a2e6923c265c7e9e64c240b805 Mon Sep 17 00:00:00 2001 From: Yegappan Lakshmanan Date: Tue, 27 Jul 2021 22:00:44 +0200 Subject: patch 8.2.3229: Vim9: runtime and compile time type checks are not the same Problem: Vim9: runtime and compile time type checks are not the same. Solution: Add more runtime type checks for builtin functions. (Yegappan Lakshmanan, closes #8646) --- src/arglist.c | 15 + src/change.c | 9 +- src/channel.c | 47 +- src/cindent.c | 3 + src/clientserver.c | 39 +- src/cmdhist.c | 11 +- src/dict.c | 8 + src/diff.c | 3 + src/digraph.c | 12 + src/errors.h | 20 + src/eval.c | 4 +- src/evalbuffer.c | 54 ++- src/evalfunc.c | 311 ++++++++++-- src/evalwindow.c | 71 ++- src/ex_docmd.c | 7 +- src/ex_getln.c | 17 +- src/filepath.c | 62 ++- src/findfile.c | 3 + src/float.c | 88 +++- src/fold.c | 10 + src/getchar.c | 3 + src/indent.c | 6 + src/insexpand.c | 8 +- src/job.c | 18 +- src/json.c | 6 + src/list.c | 5 +- src/mark.c | 3 + src/match.c | 26 +- src/mbyte.c | 9 + src/menu.c | 5 + src/misc1.c | 8 +- src/move.c | 6 + src/popupwin.c | 55 ++- src/proto/typval.pro | 7 +- src/quickfix.c | 8 + src/search.c | 3 + src/sign.c | 18 + src/sound.c | 9 +- src/strings.c | 65 ++- src/terminal.c | 67 ++- src/testdir/test_assert.vim | 2 +- src/testdir/test_blob.vim | 2 +- src/testdir/test_execute_func.vim | 2 +- src/testdir/test_float_func.vim | 3 +- src/testdir/test_functions.vim | 9 +- src/testdir/test_glob2regpat.vim | 3 +- src/testdir/test_listdict.vim | 2 +- src/testdir/test_vim9_builtin.vim | 964 +++++++++++++++++++------------------- src/testdir/test_vim9_script.vim | 2 +- src/testing.c | 61 ++- src/textprop.c | 26 +- src/time.c | 24 + src/typval.c | 106 ++++- src/undo.c | 3 + src/version.c | 2 + 55 files changed, 1710 insertions(+), 630 deletions(-) diff --git a/src/arglist.c b/src/arglist.c index 863b1cc6a9..5370142a7f 100644 --- a/src/arglist.c +++ b/src/arglist.c @@ -1271,6 +1271,9 @@ f_argc(typval_T *argvars, typval_T *rettv) { win_T *wp; + if (in_vim9script() && check_for_opt_number_arg(argvars, 0) == FAIL) + return; + if (argvars[0].v_type == VAR_UNKNOWN) // use the current window rettv->vval.v_number = ARGCOUNT; @@ -1306,6 +1309,12 @@ f_arglistid(typval_T *argvars, typval_T *rettv) { win_T *wp; + if (in_vim9script() + && (check_for_opt_number_arg(argvars, 0) == FAIL + || (argvars[0].v_type != VAR_UNKNOWN + && check_for_opt_number_arg(argvars, 1) == FAIL))) + return; + rettv->vval.v_number = -1; wp = find_tabwin(&argvars[0], &argvars[1], NULL); if (wp != NULL) @@ -1336,6 +1345,12 @@ f_argv(typval_T *argvars, typval_T *rettv) aentry_T *arglist = NULL; int argcount = -1; + if (in_vim9script() + && (check_for_opt_number_arg(argvars, 0) == FAIL + || (argvars[0].v_type != VAR_UNKNOWN + && check_for_opt_number_arg(argvars, 1) == FAIL))) + return; + if (argvars[0].v_type != VAR_UNKNOWN) { if (argvars[1].v_type == VAR_UNKNOWN) diff --git a/src/change.c b/src/change.c index f77b48c742..799aa5efbc 100644 --- a/src/change.c +++ b/src/change.c @@ -281,6 +281,9 @@ f_listener_flush(typval_T *argvars, typval_T *rettv UNUSED) { buf_T *buf = curbuf; + if (in_vim9script() && check_for_opt_buffer_arg(argvars, 0) == FAIL) + return; + if (argvars[0].v_type != VAR_UNKNOWN) { buf = get_buf_arg(&argvars[0]); @@ -299,9 +302,13 @@ f_listener_remove(typval_T *argvars, typval_T *rettv) listener_T *lnr; listener_T *next; listener_T *prev; - int id = tv_get_number(argvars); + int id; buf_T *buf; + if (in_vim9script() && check_for_number_arg(argvars, 0) == FAIL) + return; + + id = tv_get_number(argvars); FOR_ALL_BUFFERS(buf) { prev = NULL; diff --git a/src/channel.c b/src/channel.c index 46bdc0ec8a..5307792e8c 100644 --- a/src/channel.c +++ b/src/channel.c @@ -3865,6 +3865,11 @@ common_channel_read(typval_T *argvars, typval_T *rettv, int raw, int blob) rettv->v_type = VAR_STRING; rettv->vval.v_string = NULL; + if (in_vim9script() + && (check_for_chan_or_job_arg(argvars, 0) == FAIL + || check_for_opt_dict_arg(argvars, 1) == FAIL)) + return; + clear_job_options(&opt); if (get_job_options(&argvars[1], &opt, JO_TIMEOUT + JO_PART + JO_ID, 0) == FAIL) @@ -4784,9 +4789,13 @@ channel_get_timeout(channel_T *channel, ch_part_T part) void f_ch_canread(typval_T *argvars, typval_T *rettv) { - channel_T *channel = get_channel_arg(&argvars[0], FALSE, FALSE, 0); + channel_T *channel; rettv->vval.v_number = 0; + if (in_vim9script() && check_for_chan_or_job_arg(argvars, 0) == FAIL) + return; + + channel = get_channel_arg(&argvars[0], FALSE, FALSE, 0); if (channel != NULL) rettv->vval.v_number = channel_has_readahead(channel, PART_SOCK) || channel_has_readahead(channel, PART_OUT) @@ -4799,8 +4808,12 @@ f_ch_canread(typval_T *argvars, typval_T *rettv) void f_ch_close(typval_T *argvars, typval_T *rettv UNUSED) { - channel_T *channel = get_channel_arg(&argvars[0], TRUE, FALSE, 0); + channel_T *channel; + if (in_vim9script() && check_for_chan_or_job_arg(argvars, 0) == FAIL) + return; + + channel = get_channel_arg(&argvars[0], TRUE, FALSE, 0); if (channel != NULL) { channel_close(channel, FALSE); @@ -4814,8 +4827,12 @@ f_ch_close(typval_T *argvars, typval_T *rettv UNUSED) void f_ch_close_in(typval_T *argvars, typval_T *rettv UNUSED) { - channel_T *channel = get_channel_arg(&argvars[0], TRUE, FALSE, 0); + channel_T *channel; + if (in_vim9script() && check_for_chan_or_job_arg(argvars, 0) == FAIL) + return; + + channel = get_channel_arg(&argvars[0], TRUE, FALSE, 0); if (channel != NULL) channel_close_in(channel); } @@ -4861,8 +4878,12 @@ f_ch_getbufnr(typval_T *argvars, typval_T *rettv) void f_ch_getjob(typval_T *argvars, typval_T *rettv) { - channel_T *channel = get_channel_arg(&argvars[0], FALSE, FALSE, 0); + channel_T *channel; + if (in_vim9script() && check_for_chan_or_job_arg(argvars, 0) == FAIL) + return; + + channel = get_channel_arg(&argvars[0], FALSE, FALSE, 0); if (channel != NULL) { rettv->v_type = VAR_JOB; @@ -4878,8 +4899,12 @@ f_ch_getjob(typval_T *argvars, typval_T *rettv) void f_ch_info(typval_T *argvars, typval_T *rettv UNUSED) { - channel_T *channel = get_channel_arg(&argvars[0], FALSE, FALSE, 0); + channel_T *channel; + if (in_vim9script() && check_for_chan_or_job_arg(argvars, 0) == FAIL) + return; + + channel = get_channel_arg(&argvars[0], FALSE, FALSE, 0); if (channel != NULL && rettv_dict_alloc(rettv) != FAIL) channel_info(channel, rettv->vval.v_dict); } @@ -4921,7 +4946,7 @@ f_ch_logfile(typval_T *argvars, typval_T *rettv UNUSED) if (in_vim9script() && (check_for_string_arg(argvars, 0) == FAIL - || check_for_string_arg(argvars, 1) == FAIL)) + || check_for_opt_string_arg(argvars, 1) == FAIL)) return; fname = tv_get_string(&argvars[0]); @@ -5014,6 +5039,11 @@ f_ch_setoptions(typval_T *argvars, typval_T *rettv UNUSED) channel_T *channel; jobopt_T opt; + if (in_vim9script() + && (check_for_chan_or_job_arg(argvars, 0) == FAIL + || check_for_dict_arg(argvars, 1) == FAIL)) + return; + channel = get_channel_arg(&argvars[0], FALSE, FALSE, 0); if (channel == NULL) return; @@ -5038,6 +5068,11 @@ f_ch_status(typval_T *argvars, typval_T *rettv) rettv->v_type = VAR_STRING; rettv->vval.v_string = NULL; + if (in_vim9script() + && (check_for_chan_or_job_arg(argvars, 0) == FAIL + || check_for_opt_dict_arg(argvars, 1) == FAIL)) + return; + channel = get_channel_arg(&argvars[0], FALSE, FALSE, 0); if (argvars[1].v_type != VAR_UNKNOWN) diff --git a/src/cindent.c b/src/cindent.c index ce02402c22..b751206532 100644 --- a/src/cindent.c +++ b/src/cindent.c @@ -4129,6 +4129,9 @@ f_cindent(typval_T *argvars UNUSED, typval_T *rettv) pos_T pos; linenr_T lnum; + if (in_vim9script() && check_for_lnum_arg(argvars, 0) == FAIL) + return; + pos = curwin->w_cursor; lnum = tv_get_lnum(argvars); if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) diff --git a/src/clientserver.c b/src/clientserver.c index 3c0a930ed1..4ad17f4f93 100644 --- a/src/clientserver.c +++ b/src/clientserver.c @@ -814,6 +814,9 @@ f_remote_expr(typval_T *argvars UNUSED, typval_T *rettv) f_remote_foreground(typval_T *argvars UNUSED, typval_T *rettv UNUSED) { #ifdef FEAT_CLIENTSERVER + if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL) + return; + # ifdef MSWIN // On Win32 it's done in this application. { @@ -846,17 +849,18 @@ f_remote_peek(typval_T *argvars UNUSED, typval_T *rettv) # endif char_u *serverid; + rettv->vval.v_number = -1; if (check_restricted() || check_secure()) - { - rettv->vval.v_number = -1; return; - } + + if (in_vim9script() + && (check_for_string_arg(argvars, 0) == FAIL + || check_for_opt_string_arg(argvars, 1) == FAIL)) + return; + serverid = tv_get_string_chk(&argvars[0]); if (serverid == NULL) - { - rettv->vval.v_number = -1; return; // type error; errmsg already given - } # ifdef MSWIN sscanf((const char *)serverid, SCANF_HEX_LONG_U, &n); if (n == 0) @@ -959,8 +963,12 @@ f_remote_send(typval_T *argvars UNUSED, typval_T *rettv) f_remote_startserver(typval_T *argvars UNUSED, typval_T *rettv UNUSED) { #ifdef FEAT_CLIENTSERVER - char_u *server = tv_get_string_chk(&argvars[0]); + char_u *server; + + if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL) + return; + server = tv_get_string_chk(&argvars[0]); if (server == NULL) return; // type error; errmsg already given if (serverName != NULL) @@ -984,14 +992,23 @@ f_server2client(typval_T *argvars UNUSED, typval_T *rettv) { #ifdef FEAT_CLIENTSERVER char_u buf[NUMBUFLEN]; - char_u *server = tv_get_string_chk(&argvars[0]); - char_u *reply = tv_get_string_buf_chk(&argvars[1], buf); + char_u *server; + char_u *reply; rettv->vval.v_number = -1; - if (server == NULL || reply == NULL) - return; if (check_restricted() || check_secure()) return; + + if (in_vim9script() + && (check_for_string_arg(argvars, 0) == FAIL + || check_for_string_arg(argvars, 1) == FAIL)) + return; + + server = tv_get_string_chk(&argvars[0]); + reply = tv_get_string_buf_chk(&argvars[1], buf); + if (server == NULL || reply == NULL) + return; + # ifdef FEAT_X11 if (check_connection() == FAIL) return; diff --git a/src/cmdhist.c b/src/cmdhist.c index f3b8b007eb..0ac3ff6949 100644 --- a/src/cmdhist.c +++ b/src/cmdhist.c @@ -545,6 +545,12 @@ f_histadd(typval_T *argvars UNUSED, typval_T *rettv) rettv->vval.v_number = FALSE; if (check_secure()) return; + + if (in_vim9script() + && (check_for_string_arg(argvars, 0) == FAIL + || check_for_string_arg(argvars, 1) == FAIL)) + return; + str = tv_get_string_chk(&argvars[0]); // NULL on type error histype = str != NULL ? get_histtype(str) : -1; if (histype >= 0) @@ -630,9 +636,12 @@ f_histget(typval_T *argvars UNUSED, typval_T *rettv) f_histnr(typval_T *argvars UNUSED, typval_T *rettv) { int i; + char_u *histname; - char_u *histname = tv_get_string_chk(&argvars[0]); + if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL) + return; + histname = tv_get_string_chk(&argvars[0]); i = histname == NULL ? HIST_CMD - 1 : get_histtype(histname); if (i >= HIST_CMD && i < HIST_COUNT) i = get_history_idx(i); diff --git a/src/dict.c b/src/dict.c index 768adf0de5..82397d5126 100644 --- a/src/dict.c +++ b/src/dict.c @@ -1201,6 +1201,9 @@ dict_list(typval_T *argvars, typval_T *rettv, int what) dict_T *d; int todo; + if (in_vim9script() && check_for_dict_arg(argvars, 0) == FAIL) + return; + if (argvars[0].v_type != VAR_DICT) { emsg(_(e_dictreq)); @@ -1318,6 +1321,11 @@ dict_set_items_ro(dict_T *di) void f_has_key(typval_T *argvars, typval_T *rettv) { + if (in_vim9script() + && (check_for_dict_arg(argvars, 0) == FAIL + || check_for_string_or_number_arg(argvars, 1) == FAIL)) + return; + if (argvars[0].v_type != VAR_DICT) { emsg(_(e_dictreq)); diff --git a/src/diff.c b/src/diff.c index a47259e1af..aea1c0e70a 100644 --- a/src/diff.c +++ b/src/diff.c @@ -3272,6 +3272,9 @@ xdiff_out(void *priv, mmbuffer_t *mb, int nbuf) f_diff_filler(typval_T *argvars UNUSED, typval_T *rettv UNUSED) { #ifdef FEAT_DIFF + if (in_vim9script() && check_for_lnum_arg(argvars, 0) == FAIL) + return; + rettv->vval.v_number = diff_check_fill(curwin, tv_get_lnum(argvars)); #endif } diff --git a/src/digraph.c b/src/digraph.c index 745cbbb746..4a185399da 100644 --- a/src/digraph.c +++ b/src/digraph.c @@ -2406,6 +2406,10 @@ f_digraph_get(typval_T *argvars, typval_T *rettv) rettv->v_type = VAR_STRING; rettv->vval.v_string = NULL; // Return empty string for failure + + if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL) + return; + digraphs = tv_get_string_chk(&argvars[0]); if (digraphs == NULL) @@ -2439,6 +2443,9 @@ f_digraph_getlist(typval_T *argvars, typval_T *rettv) # ifdef FEAT_DIGRAPHS int flag_list_all; + if (in_vim9script() && check_for_opt_number_arg(argvars, 0) == FAIL) + return; + if (argvars[0].v_type == VAR_UNKNOWN) flag_list_all = FALSE; else @@ -2466,6 +2473,11 @@ f_digraph_set(typval_T *argvars, typval_T *rettv) rettv->v_type = VAR_BOOL; rettv->vval.v_number = VVAL_FALSE; + if (in_vim9script() + && (check_for_string_arg(argvars, 0) == FAIL + || check_for_number_arg(argvars, 1) == FAIL)) + return; + if (!digraph_set_common(&argvars[0], &argvars[1])) return; diff --git a/src/errors.h b/src/errors.h index 7e4a465223..b76b92fa5f 100644 --- a/src/errors.h +++ b/src/errors.h @@ -617,3 +617,23 @@ EXTERN char e_chan_or_job_required_for_argument_nr[] INIT(= N_("E1217: Channel or Job required for argument %d")); EXTERN char e_job_required_for_argument_nr[] INIT(= N_("E1218: Job required for argument %d")); +EXTERN char e_float_or_number_required_for_argument_nr[] + INIT(= N_("E1219: Float or Number required for argument %d")); +EXTERN char e_string_or_number_required_for_argument_nr[] + INIT(= N_("E1220: String or Number required for argument %d")); +EXTERN char e_string_or_blob_required_for_argument_nr[] + INIT(= N_("E1221: String or Blob required for argument %d")); +EXTERN char e_string_or_list_required_for_argument_nr[] + INIT(= N_("E1222: String or List required for argument %d")); +EXTERN char e_string_or_dict_required_for_argument_nr[] + INIT(= N_("E1223: String or List required for argument %d")); +EXTERN char e_string_or_number_or_list_required_for_argument_nr[] + INIT(= N_("E1224: String or List required for argument %d")); +EXTERN char e_string_or_list_or_dict_required_for_argument_nr[] + INIT(= N_("E1225: String or List required for argument %d")); +EXTERN char e_list_or_blob_required_for_argument_nr[] + INIT(= N_("E1226: String or List required for argument %d")); +EXTERN char e_list_or_dict_required_for_argument_nr[] + INIT(= N_("E1227: List or Dictionary required for argument %d")); +EXTERN char e_list_or_dict_or_blob_required_for_argument_nr[] + INIT(= N_("E1228: List or Dictionary or Blob required for argument %d")); diff --git a/src/eval.c b/src/eval.c index 8050bbbbe9..0d41f17805 100644 --- a/src/eval.c +++ b/src/eval.c @@ -4190,9 +4190,9 @@ check_can_index(typval_T *rettv, int evaluate, int verbose) f_slice(typval_T *argvars, typval_T *rettv) { if (in_vim9script() - && ((argvars[0].v_type != VAR_LIST + && ((argvars[0].v_type != VAR_STRING + && argvars[0].v_type != VAR_LIST && argvars[0].v_type != VAR_BLOB - && argvars[0].v_type != VAR_STRING && check_for_list_arg(argvars, 0) == FAIL) || check_for_number_arg(argvars, 1) == FAIL || check_for_opt_number_arg(argvars, 2) == FAIL)) diff --git a/src/evalbuffer.c b/src/evalbuffer.c index bb6ff63dfe..3fb037c5f1 100644 --- a/src/evalbuffer.c +++ b/src/evalbuffer.c @@ -277,8 +277,12 @@ done: void f_append(typval_T *argvars, typval_T *rettv) { - linenr_T lnum = tv_get_lnum(&argvars[0]); + linenr_T lnum; + + if (in_vim9script() && check_for_lnum_arg(argvars, 0) == FAIL) + return; + lnum = tv_get_lnum(&argvars[0]); set_buffer_lines(curbuf, lnum, TRUE, &argvars[1], rettv); } @@ -291,6 +295,12 @@ f_appendbufline(typval_T *argvars, typval_T *rettv) linenr_T lnum; buf_T *buf; + if (in_vim9script() + && (check_for_buffer_arg(argvars, 0) == FAIL + || check_for_lnum_arg(argvars, 1) == FAIL + || check_for_string_or_number_or_list_arg(argvars, 2) == FAIL)) + return; + buf = tv_get_buf(&argvars[0], FALSE); if (buf == NULL) rettv->vval.v_number = 1; // FAIL @@ -307,8 +317,12 @@ f_appendbufline(typval_T *argvars, typval_T *rettv) void f_bufadd(typval_T *argvars, typval_T *rettv) { - char_u *name = tv_get_string(&argvars[0]); + char_u *name; + if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL) + return; + + name = tv_get_string(&argvars[0]); rettv->vval.v_number = buflist_add(*name == NUL ? NULL : name, 0); } @@ -318,6 +332,9 @@ f_bufadd(typval_T *argvars, typval_T *rettv) void f_bufexists(typval_T *argvars, typval_T *rettv) { + if (in_vim9script() && check_for_buffer_arg(argvars, 0) == FAIL) + return; + rettv->vval.v_number = (find_buffer(&argvars[0]) != NULL); } @@ -329,6 +346,9 @@ f_buflisted(typval_T *argvars, typval_T *rettv) { buf_T *buf; + if (in_vim9script() && check_for_buffer_arg(argvars, 0) == FAIL) + return; + buf = find_buffer(&argvars[0]); rettv->vval.v_number = (buf != NULL && buf->b_p_bl); } @@ -339,8 +359,12 @@ f_buflisted(typval_T *argvars, typval_T *rettv) void f_bufload(typval_T *argvars, typval_T *rettv UNUSED) { - buf_T *buf = get_buf_arg(&argvars[0]); + buf_T *buf; + if (in_vim9script() && check_for_buffer_arg(argvars, 0) == FAIL) + return; + + buf = get_buf_arg(&argvars[0]); if (buf != NULL) buffer_ensure_loaded(buf); } @@ -353,6 +377,9 @@ f_bufloaded(typval_T *argvars, typval_T *rettv) { buf_T *buf; + if (in_vim9script() && check_for_buffer_arg(argvars, 0) == FAIL) + return; + buf = find_buffer(&argvars[0]); rettv->vval.v_number = (buf != NULL && buf->b_ml.ml_mfp != NULL); } @@ -366,6 +393,9 @@ f_bufname(typval_T *argvars, typval_T *rettv) buf_T *buf; typval_T *tv = &argvars[0]; + if (in_vim9script() && check_for_opt_buffer_arg(argvars, 0) == FAIL) + return; + if (tv->v_type == VAR_UNKNOWN) buf = curbuf; else @@ -421,6 +451,9 @@ buf_win_common(typval_T *argvars, typval_T *rettv, int get_nr) int winnr = 0; buf_T *buf; + if (in_vim9script() && check_for_buffer_arg(argvars, 0) == FAIL) + return; + buf = tv_get_buf_from_arg(&argvars[0]); FOR_ALL_WINDOWS(wp) { @@ -636,8 +669,7 @@ f_getbufinfo(typval_T *argvars, typval_T *rettv) return; if (in_vim9script() - && argvars[0].v_type != VAR_UNKNOWN - && check_for_buffer_or_dict_arg(argvars, 0) == FAIL) + && check_for_opt_buffer_or_dict_arg(argvars, 0) == FAIL) return; // List of all the buffers or selected buffers @@ -808,6 +840,12 @@ f_setbufline(typval_T *argvars, typval_T *rettv) linenr_T lnum; buf_T *buf; + if (in_vim9script() + && (check_for_buffer_arg(argvars, 0) == FAIL + || check_for_lnum_arg(argvars, 1) == FAIL + || check_for_string_or_number_or_list_arg(argvars, 2) == FAIL)) + return; + buf = tv_get_buf(&argvars[0], FALSE); if (buf == NULL) rettv->vval.v_number = 1; // FAIL @@ -824,8 +862,12 @@ f_setbufline(typval_T *argvars, typval_T *rettv) void f_setline(typval_T *argvars, typval_T *rettv) { - linenr_T lnum = tv_get_lnum(&argvars[0]); + linenr_T lnum; + + if (in_vim9script() && check_for_lnum_arg(argvars, 0) == FAIL) + return; + lnum = tv_get_lnum(&argvars[0]); set_buffer_lines(curbuf, lnum, FALSE, &argvars[1], rettv); } #endif // FEAT_EVAL diff --git a/src/evalfunc.c b/src/evalfunc.c index 2a9c972f99..7fc1821c6c 100644 --- a/src/evalfunc.c +++ b/src/evalfunc.c @@ -762,7 +762,7 @@ static argcheck_T arg3_string_number_bool[] = {arg_string, arg_number, arg_bool} static argcheck_T arg3_string_number_number[] = {arg_string, arg_number, arg_number}; static argcheck_T arg3_string_string_bool[] = {arg_string, arg_string, arg_bool}; static argcheck_T arg3_string_string_dict[] = {arg_string, arg_string, arg_dict_any}; -static argcheck_T arg3_string_string_nr[] = {arg_string, arg_string, arg_number}; +static argcheck_T arg3_string_string_number[] = {arg_string, arg_string, arg_number}; static argcheck_T arg4_list_number_number_number[] = {arg_list_string, arg_number, arg_number, arg_number}; static argcheck_T arg4_number_number_string_any[] = {arg_number, arg_number, arg_string, NULL}; static argcheck_T arg4_string_string_any_string[] = {arg_string, arg_string, NULL, arg_string}; @@ -811,7 +811,7 @@ static argcheck_T arg24_strpart[] = {arg_string, arg_number, arg_number, arg_boo static argcheck_T arg12_system[] = {arg_string, arg_str_or_nr_or_list}; static argcheck_T arg23_win_execute[] = {arg_number, arg_string_or_list_string, arg_string}; static argcheck_T arg23_writefile[] = {arg_list_or_blob, arg_string, arg_string}; -static argcheck_T arg4_match_func[] = {arg_string_or_list_any, arg_string, arg_number, arg_number}; +static argcheck_T arg24_match_func[] = {arg_string_or_list_any, arg_string, arg_number, arg_number}; /* @@ -1340,9 +1340,9 @@ static funcentry_T global_functions[] = ret_number, f_filewritable}, {"filter", 2, 2, FEARG_1, arg2_mapfilter, ret_first_arg, f_filter}, - {"finddir", 1, 3, FEARG_1, arg3_string_string_nr, + {"finddir", 1, 3, FEARG_1, arg3_string_string_number, ret_string, f_finddir}, - {"findfile", 1, 3, FEARG_1, arg3_string_string_nr, + {"findfile", 1, 3, FEARG_1, arg3_string_string_number, ret_string, f_findfile}, {"flatten", 1, 2, FEARG_1, arg2_list_any_number, ret_list_any, f_flatten}, @@ -1608,7 +1608,7 @@ static funcentry_T global_functions[] = ret_first_cont, f_mapnew}, {"mapset", 3, 3, FEARG_1, arg3_string_bool_dict, ret_void, f_mapset}, - {"match", 2, 4, FEARG_1, arg4_match_func, + {"match", 2, 4, FEARG_1, arg24_match_func, ret_any, f_match}, {"matchadd", 2, 5, FEARG_1, arg25_matchadd, ret_number, f_matchadd}, @@ -1618,17 +1618,17 @@ static funcentry_T global_functions[] = ret_list_string, f_matcharg}, {"matchdelete", 1, 2, FEARG_1, arg2_number, ret_number_bool, f_matchdelete}, - {"matchend", 2, 4, FEARG_1, arg4_match_func, + {"matchend", 2, 4, FEARG_1, arg24_match_func, ret_number, f_matchend}, {"matchfuzzy", 2, 3, FEARG_1, arg3_list_string_dict, ret_list_string, f_matchfuzzy}, {"matchfuzzypos", 2, 3, FEARG_1, arg3_list_string_dict, ret_list_any, f_matchfuzzypos}, - {"matchlist", 2, 4, FEARG_1, arg4_match_func, + {"matchlist", 2, 4, FEARG_1, arg24_match_func, ret_list_string, f_matchlist}, - {"matchstr", 2, 4, FEARG_1, arg4_match_func, + {"matchstr", 2, 4, FEARG_1, arg24_match_func, ret_string, f_matchstr}, - {"matchstrpos", 2, 4, FEARG_1, arg4_match_func, + {"matchstrpos", 2, 4, FEARG_1, arg24_match_func, ret_list_any, f_matchstrpos}, {"max", 1, 1, FEARG_1, arg1_list_or_dict, ret_number, f_max}, @@ -1642,7 +1642,7 @@ static funcentry_T global_functions[] = }, {"min", 1, 1, FEARG_1, arg1_list_or_dict, ret_number, f_min}, - {"mkdir", 1, 3, FEARG_1, arg3_string_string_nr, + {"mkdir", 1, 3, FEARG_1, arg3_string_string_number, ret_number_bool, f_mkdir}, {"mode", 0, 1, FEARG_1, arg1_bool, ret_string, f_mode}, @@ -1784,7 +1784,7 @@ static funcentry_T global_functions[] = ret_list_string, f_readdir}, {"readdirex", 1, 3, FEARG_1, arg3_string_any_dict, ret_list_dict_any, f_readdirex}, - {"readfile", 1, 3, FEARG_1, arg3_string_string_nr, + {"readfile", 1, 3, FEARG_1, arg3_string_string_number, ret_list_string, f_readfile}, {"reduce", 2, 3, FEARG_1, arg23_reduce, ret_any, f_reduce}, @@ -1984,7 +1984,7 @@ static funcentry_T global_functions[] = }, {"strgetchar", 2, 2, FEARG_1, arg2_string_number, ret_number, f_strgetchar}, - {"stridx", 2, 3, FEARG_1, arg3_string_string_nr, + {"stridx", 2, 3, FEARG_1, arg3_string_string_number, ret_number, f_stridx}, {"string", 1, 1, FEARG_1, NULL, ret_string, f_string}, @@ -2000,7 +2000,7 @@ static funcentry_T global_functions[] = NULL #endif }, - {"strridx", 2, 3, FEARG_1, arg3_string_string_nr, + {"strridx", 2, 3, FEARG_1, arg3_string_string_number, ret_number, f_strridx}, {"strtrans", 1, 1, FEARG_1, arg1_string, ret_string, f_strtrans}, @@ -2180,7 +2180,7 @@ static funcentry_T global_functions[] = ret_string, f_toupper}, {"tr", 3, 3, FEARG_1, arg3_string, ret_string, f_tr}, - {"trim", 1, 3, FEARG_1, arg3_string_string_nr, + {"trim", 1, 3, FEARG_1, arg3_string_string_number, ret_string, f_trim}, {"trunc", 1, 1, FEARG_1, arg1_float_or_nr, ret_float, FLOAT_FUNC(f_trunc)}, @@ -2607,6 +2607,11 @@ non_zero_arg(typval_T *argvars) static void f_and(typval_T *argvars, typval_T *rettv) { + if (in_vim9script() + && (check_for_number_arg(argvars, 0) == FAIL + || check_for_number_arg(argvars, 1) == FAIL)) + return; + rettv->vval.v_number = tv_get_number_chk(&argvars[0], NULL) & tv_get_number_chk(&argvars[1], NULL); } @@ -2633,6 +2638,10 @@ f_balloon_show(typval_T *argvars, typval_T *rettv UNUSED) { if (balloonEval != NULL) { + if (in_vim9script() + && check_for_string_or_list_arg(argvars, 0) == FAIL) + return; + if (argvars[0].v_type == VAR_LIST # ifdef FEAT_GUI && !gui.in_use @@ -2717,6 +2726,9 @@ f_byte2line(typval_T *argvars UNUSED, typval_T *rettv) #else long boff = 0; + if (in_vim9script() && check_for_number_arg(argvars, 0) == FAIL) + return; + boff = tv_get_number(&argvars[0]) - 1; // boff gets -1 on type error if (boff < 0) rettv->vval.v_number = -1; @@ -2822,6 +2834,10 @@ get_col(typval_T *argvars, typval_T *rettv, int charcol) pos_T *fp; int fnum = curbuf->b_fnum; + if (in_vim9script() + && check_for_string_or_list_arg(argvars, 0) == FAIL) + return; + fp = var2fpos(&argvars[0], FALSE, &fnum, charcol); if (fp != NULL && fnum == curbuf->b_fnum) { @@ -2982,10 +2998,7 @@ set_cursorpos(typval_T *argvars, typval_T *rettv, int charcol) int set_curswant = TRUE; if (in_vim9script() - && ((argvars[0].v_type != VAR_NUMBER - && argvars[0].v_type != VAR_STRING - && argvars[0].v_type != VAR_LIST - && check_for_number_arg(argvars, 0) == FAIL) + && (check_for_string_or_number_or_list_arg(argvars, 0) == FAIL || check_for_opt_number_arg(argvars, 1) == FAIL || (argvars[1].v_type != VAR_UNKNOWN && check_for_opt_number_arg(argvars, 2) == FAIL))) @@ -3071,6 +3084,9 @@ f_debugbreak(typval_T *argvars, typval_T *rettv) int pid; rettv->vval.v_number = FAIL; + if (in_vim9script() && check_for_number_arg(argvars, 0) == FAIL) + return; + pid = (int)tv_get_number(&argvars[0]); if (pid == 0) emsg(_(e_invarg)); @@ -3269,6 +3285,11 @@ f_escape(typval_T *argvars, typval_T *rettv) { char_u buf[NUMBUFLEN]; + if (in_vim9script() + && (check_for_string_arg(argvars, 0) == FAIL + || check_for_string_arg(argvars, 1) == FAIL)) + return; + rettv->vval.v_string = vim_strsave_escaped(tv_get_string(&argvars[0]), tv_get_string_buf(&argvars[1], buf)); rettv->v_type = VAR_STRING; @@ -3282,6 +3303,9 @@ f_eval(typval_T *argvars, typval_T *rettv) { char_u *s, *p; + if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL) + return; + s = tv_get_string_chk(&argvars[0]); if (s != NULL) s = skipwhite(s); @@ -3475,6 +3499,11 @@ execute_common(typval_T *argvars, typval_T *rettv, int arg_off) static void f_execute(typval_T *argvars, typval_T *rettv) { + if (in_vim9script() + && (check_for_string_or_list_arg(argvars, 0) == FAIL + || check_for_opt_string_arg(argvars, 1) == FAIL)) + return; + execute_common(argvars, rettv, 0); } @@ -3487,6 +3516,9 @@ f_exists(typval_T *argvars, typval_T *rettv) char_u *p; int n = FALSE; + if (in_vim9script() && check_for_nonempty_string_arg(argvars, 0) == FAIL) + return; + p = tv_get_string(&argvars[0]); if (*p == '$') // environment variable { @@ -3631,6 +3663,9 @@ f_expandcmd(typval_T *argvars, typval_T *rettv) char_u *cmdstr; char *errormsg = NULL; + if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL) + return; + rettv->v_type = VAR_STRING; cmdstr = vim_strsave(tv_get_string(&argvars[0])); @@ -3671,6 +3706,11 @@ f_feedkeys(typval_T *argvars, typval_T *rettv UNUSED) if (check_secure()) return; + if (in_vim9script() + && (check_for_string_arg(argvars, 0) == FAIL + || check_for_opt_string_arg(argvars, 1) == FAIL)) + return; + keys = tv_get_string(&argvars[0]); if (argvars[1].v_type != VAR_UNKNOWN) @@ -3760,6 +3800,9 @@ f_feedkeys(typval_T *argvars, typval_T *rettv UNUSED) static void f_fnameescape(typval_T *argvars, typval_T *rettv) { + if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL) + return; + rettv->vval.v_string = vim_strsave_fnameescape( tv_get_string(&argvars[0]), FALSE); rettv->v_type = VAR_STRING; @@ -4029,6 +4072,9 @@ f_function(typval_T *argvars, typval_T *rettv) static void f_garbagecollect(typval_T *argvars, typval_T *rettv UNUSED) { + if (in_vim9script() && check_for_opt_bool_arg(argvars, 0) == FAIL) + return; + // This is postponed until we are back at the toplevel, because we may be // using Lists and Dicts internally. E.g.: ":echo [garbagecollect()]". want_garbage_collect = TRUE; @@ -4175,6 +4221,9 @@ f_getchangelist(typval_T *argvars, typval_T *rettv) if (rettv_list_alloc(rettv) != OK) return; + if (in_vim9script() && check_for_opt_buffer_arg(argvars, 0) == FAIL) + return; + #ifdef FEAT_JUMPLIST if (argvars[0].v_type == VAR_UNKNOWN) buf = curbuf; @@ -4292,6 +4341,9 @@ getpos_both( static void f_getcharpos(typval_T *argvars UNUSED, typval_T *rettv) { + if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL) + return; + getpos_both(argvars, rettv, FALSE, TRUE); } @@ -4318,8 +4370,12 @@ f_getcharsearch(typval_T *argvars UNUSED, typval_T *rettv) f_getenv(typval_T *argvars, typval_T *rettv) { int mustfree = FALSE; - char_u *p = vim_getenv(tv_get_string(&argvars[0]), &mustfree); + char_u *p; + if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL) + return; + + p = vim_getenv(tv_get_string(&argvars[0]), &mustfree); if (p == NULL) { rettv->v_type = VAR_SPECIAL; @@ -4340,6 +4396,10 @@ f_getfontname(typval_T *argvars UNUSED, typval_T *rettv) { rettv->v_type = VAR_STRING; rettv->vval.v_string = NULL; + + if (in_vim9script() && check_for_opt_string_arg(argvars, 0) == FAIL) + return; + #ifdef FEAT_GUI if (gui.in_use) { @@ -4385,6 +4445,12 @@ f_getjumplist(typval_T *argvars, typval_T *rettv) if (rettv_list_alloc(rettv) != OK) return; + if (in_vim9script() + && (check_for_opt_number_arg(argvars, 0) == FAIL + || (argvars[0].v_type != VAR_UNKNOWN + && check_for_opt_number_arg(argvars, 1) == FAIL))) + return; + #ifdef FEAT_JUMPLIST wp = find_tabwin(&argvars[0], &argvars[1], NULL); if (wp == NULL) @@ -4433,12 +4499,18 @@ f_getpid(typval_T *argvars UNUSED, typval_T *rettv) static void f_getcurpos(typval_T *argvars, typval_T *rettv) { + if (in_vim9script() && check_for_opt_number_arg(argvars, 0) == FAIL) + return; + getpos_both(argvars, rettv, TRUE, FALSE); } static void f_getcursorcharpos(typval_T *argvars, typval_T *rettv) { + if (in_vim9script() && check_for_opt_number_arg(argvars, 0) == FAIL) + return; + getpos_both(argvars, rettv, TRUE, TRUE); } @@ -4448,6 +4520,9 @@ f_getcursorcharpos(typval_T *argvars, typval_T *rettv) static void f_getpos(typval_T *argvars, typval_T *rettv) { + if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL) + return; + getpos_both(argvars, rettv, FALSE, FALSE); } @@ -4464,10 +4539,11 @@ f_getreg(typval_T *argvars, typval_T *rettv) int error = FALSE; if (in_vim9script() - && (check_for_string_arg(argvars, 0) == FAIL - || check_for_opt_bool_arg(argvars, 1) == FAIL - || (argvars[1].v_type != VAR_UNKNOWN - && check_for_opt_bool_arg(argvars, 2) == FAIL))) + && (check_for_opt_string_arg(argvars, 0) == FAIL + || (argvars[0].v_type != VAR_UNKNOWN + && (check_for_opt_bool_arg(argvars, 1) == FAIL + || (argvars[1].v_type != VAR_UNKNOWN + && check_for_opt_bool_arg(argvars, 2) == FAIL))))) return; if (argvars[0].v_type != VAR_UNKNOWN) @@ -4526,6 +4602,9 @@ f_getregtype(typval_T *argvars, typval_T *rettv) char_u buf[NUMBUFLEN + 2]; long reglen = 0; + if (in_vim9script() && check_for_opt_string_arg(argvars, 0) == FAIL) + return; + if (argvars[0].v_type != VAR_UNKNOWN) { strregname = tv_get_string_chk(&argvars[0]); @@ -4575,6 +4654,9 @@ f_gettagstack(typval_T *argvars, typval_T *rettv) if (rettv_dict_alloc(rettv) != OK) return; + if (in_vim9script() && check_for_opt_number_arg(argvars, 0) == FAIL) + return; + if (argvars[0].v_type != VAR_UNKNOWN) { wp = find_win_by_nr_or_id(&argvars[0]); @@ -4591,6 +4673,9 @@ f_gettagstack(typval_T *argvars, typval_T *rettv) static void f_gettext(typval_T *argvars, typval_T *rettv) { + if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL) + return; + if (argvars[0].v_type != VAR_STRING || argvars[0].vval.v_string == NULL || *argvars[0].vval.v_string == NUL) @@ -6023,6 +6108,12 @@ f_haslocaldir(typval_T *argvars, typval_T *rettv) tabpage_T *tp = NULL; win_T *wp = NULL; + if (in_vim9script() + && (check_for_opt_number_arg(argvars, 0) == FAIL + || (argvars[0].v_type != VAR_UNKNOWN + && check_for_opt_number_arg(argvars, 1) == FAIL))) + return; + wp = find_tabwin(&argvars[0], &argvars[1], &tp); // Check for window-local and tab-local directories @@ -6074,6 +6165,9 @@ f_hasmapto(typval_T *argvars, typval_T *rettv) static void f_hlID(typval_T *argvars, typval_T *rettv) { + if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL) + return; + rettv->vval.v_number = syn_name2id(tv_get_string(&argvars[0])); } @@ -6083,6 +6177,9 @@ f_hlID(typval_T *argvars, typval_T *rettv) static void f_hlexists(typval_T *argvars, typval_T *rettv) { + if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL) + return; + rettv->vval.v_number = highlight_exists(tv_get_string(&argvars[0])); } @@ -6214,6 +6311,13 @@ f_inputdialog(typval_T *argvars, typval_T *rettv) char_u buf[NUMBUFLEN]; char_u *defstr = (char_u *)""; + if (in_vim9script() + && (check_for_string_arg(argvars, 0) == FAIL + || check_for_opt_string_arg(argvars, 1) == FAIL + || (argvars[1].v_type != VAR_UNKNOWN + && check_for_opt_string_arg(argvars, 2) == FAIL))) + return; + message = tv_get_string_chk(&argvars[0]); if (argvars[1].v_type != VAR_UNKNOWN && (defstr = tv_get_string_buf_chk(&argvars[1], buf)) != NULL) @@ -6258,6 +6362,9 @@ f_inputlist(typval_T *argvars, typval_T *rettv) if (no_console_input() && !is_not_a_term()) return; #endif + if (in_vim9script() && check_for_list_arg(argvars, 0) == FAIL) + return; + if (argvars[0].v_type != VAR_LIST || argvars[0].vval.v_list == NULL) { semsg(_(e_listarg), "inputlist()"); @@ -6332,6 +6439,11 @@ f_inputsave(typval_T *argvars UNUSED, typval_T *rettv) static void f_inputsecret(typval_T *argvars, typval_T *rettv) { + if (in_vim9script() + && (check_for_string_arg(argvars, 0) == FAIL + || check_for_opt_string_arg(argvars, 1) == FAIL)) + return; + ++cmdline_star; ++inputsecret_flag; f_input(argvars, rettv); @@ -6354,6 +6466,9 @@ f_interrupt(typval_T *argvars UNUSED, typval_T *rettv UNUSED) static void f_invert(typval_T *argvars, typval_T *rettv) { + if (in_vim9script() && check_for_number_arg(argvars, 0) == FAIL) + return; + rettv->vval.v_number = ~tv_get_number_chk(&argvars[0], NULL); } @@ -6585,6 +6700,9 @@ f_line2byte(typval_T *argvars UNUSED, typval_T *rettv) #else linenr_T lnum; + if (in_vim9script() && check_for_lnum_arg(argvars, 0) == FAIL) + return; + lnum = tv_get_lnum(argvars); if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count + 1) rettv->vval.v_number = -1; @@ -6712,9 +6830,7 @@ find_some_match(typval_T *argvars, typval_T *rettv, matchtype_T type) } if (in_vim9script() - && ((argvars[0].v_type != VAR_STRING - && argvars[0].v_type != VAR_LIST - && check_for_string_arg(argvars, 0) == FAIL) + && (check_for_string_or_list_arg(argvars, 0) == FAIL || check_for_string_arg(argvars, 1) == FAIL || check_for_opt_number_arg(argvars, 2) == FAIL || (argvars[2].v_type != VAR_UNKNOWN @@ -6947,6 +7063,9 @@ max_min(typval_T *argvars, typval_T *rettv, int domax) varnumber_T i; int error = FALSE; + if (in_vim9script() && check_for_list_or_dict_arg(argvars, 0) == FAIL) + return; + if (argvars[0].v_type == VAR_LIST) { list_T *l; @@ -7052,6 +7171,10 @@ f_mzeval(typval_T *argvars, typval_T *rettv) if (check_restricted() || check_secure()) return; + + if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL) + return; + str = tv_get_string_buf(&argvars[0], buf); do_mzeval(str, rettv); } @@ -7078,6 +7201,9 @@ f_nextnonblank(typval_T *argvars, typval_T *rettv) { linenr_T lnum; + if (in_vim9script() && check_for_lnum_arg(argvars, 0) == FAIL) + return; + for (lnum = tv_get_lnum(argvars); ; ++lnum) { if (lnum < 0 || lnum > curbuf->b_ml.ml_line_count) @@ -7130,6 +7256,11 @@ f_nr2char(typval_T *argvars, typval_T *rettv) static void f_or(typval_T *argvars, typval_T *rettv) { + if (in_vim9script() + && (check_for_number_arg(argvars, 0) == FAIL + || check_for_number_arg(argvars, 1) == FAIL)) + return; + rettv->vval.v_number = tv_get_number_chk(&argvars[0], NULL) | tv_get_number_chk(&argvars[1], NULL); } @@ -7144,6 +7275,9 @@ f_perleval(typval_T *argvars, typval_T *rettv) char_u *str; char_u buf[NUMBUFLEN]; + if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL) + return; + str = tv_get_string_buf(&argvars[0], buf); do_perleval(str, rettv); } @@ -7157,6 +7291,9 @@ f_prevnonblank(typval_T *argvars, typval_T *rettv) { linenr_T lnum; + if (in_vim9script() && check_for_lnum_arg(argvars, 0) == FAIL) + return; + lnum = tv_get_lnum(argvars); if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count) lnum = 0; @@ -7241,6 +7378,9 @@ f_py3eval(typval_T *argvars, typval_T *rettv) if (check_restricted() || check_secure()) return; + if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL) + return; + if (p_pyx == 0) p_pyx = 3; @@ -7262,6 +7402,9 @@ f_pyeval(typval_T *argvars, typval_T *rettv) if (check_restricted() || check_secure()) return; + if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL) + return; + if (p_pyx == 0) p_pyx = 2; @@ -7280,6 +7423,9 @@ f_pyxeval(typval_T *argvars, typval_T *rettv) if (check_restricted() || check_secure()) return; + if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL) + return; + # if defined(FEAT_PYTHON) && defined(FEAT_PYTHON3) init_pyxversion(); if (p_pyx == 2) @@ -7300,6 +7446,9 @@ static int srand_seed_for_testing_is_used = FALSE; static void f_test_srand_seed(typval_T *argvars, typval_T *rettv UNUSED) { + if (in_vim9script() && check_for_opt_number_arg(argvars, 0) == FAIL) + return; + if (argvars[0].v_type == VAR_UNKNOWN) srand_seed_for_testing_is_used = FALSE; else @@ -7383,6 +7532,9 @@ f_rand(typval_T *argvars, typval_T *rettv) listitem_T *lx, *ly, *lz, *lw; UINT32_T x = 0, y, z, w, t, result; + if (in_vim9script() && check_for_opt_list_arg(argvars, 0) == FAIL) + return; + if (argvars[0].v_type == VAR_UNKNOWN) { // When no argument is given use the global seed list. @@ -7449,6 +7601,10 @@ f_srand(typval_T *argvars, typval_T *rettv) if (rettv_list_alloc(rettv) == FAIL) return; + + if (in_vim9script() && check_for_opt_number_arg(argvars, 0) == FAIL) + return; + if (argvars[0].v_type == VAR_UNKNOWN) { init_srand(&x); @@ -7483,6 +7639,13 @@ f_range(typval_T *argvars, typval_T *rettv) varnumber_T stride = 1; int error = FALSE; + if (in_vim9script() + && (check_for_number_arg(argvars, 0) == FAIL + || check_for_opt_number_arg(argvars, 1) == FAIL + || (argvars[1].v_type != VAR_UNKNOWN + && check_for_opt_number_arg(argvars, 2) == FAIL))) + return; + start = tv_get_number_chk(&argvars[0], &error); if (argvars[1].v_type == VAR_UNKNOWN) { @@ -7551,6 +7714,9 @@ f_getreginfo(typval_T *argvars, typval_T *rettv) dict_T *dict; list_T *list; + if (in_vim9script() && check_for_opt_string_arg(argvars, 0) == FAIL) + return; + if (argvars[0].v_type != VAR_UNKNOWN) { strregname = tv_get_string_chk(&argvars[0]); @@ -7645,10 +7811,16 @@ f_rename(typval_T *argvars, typval_T *rettv) { char_u buf[NUMBUFLEN]; + rettv->vval.v_number = -1; if (check_restricted() || check_secure()) - rettv->vval.v_number = -1; - else - rettv->vval.v_number = vim_rename(tv_get_string(&argvars[0]), + return; + + if (in_vim9script() + && (check_for_string_arg(argvars, 0) == FAIL + || check_for_string_arg(argvars, 1) == FAIL)) + return; + + rettv->vval.v_number = vim_rename(tv_get_string(&argvars[0]), tv_get_string_buf(&argvars[1], buf)); } @@ -7666,10 +7838,8 @@ f_repeat(typval_T *argvars, typval_T *rettv) int i; if (in_vim9script() - && (argvars[0].v_type != VAR_STRING - && argvars[0].v_type != VAR_NUMBER - && argvars[0].v_type != VAR_LIST - && check_for_string_arg(argvars, 0) == FAIL)) + && (check_for_string_or_number_or_list_arg(argvars, 0) == FAIL + || check_for_number_arg(argvars, 1) == FAIL)) return; n = (int)tv_get_number(&argvars[1]); @@ -7932,6 +8102,9 @@ f_rubyeval(typval_T *argvars, typval_T *rettv) char_u *str; char_u buf[NUMBUFLEN]; + if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL) + return; + str = tv_get_string_buf(&argvars[0], buf); do_rubyeval(str, rettv); } @@ -7947,6 +8120,11 @@ f_screenattr(typval_T *argvars, typval_T *rettv) int col; int c; + if (in_vim9script() + && (check_for_number_arg(argvars, 0) == FAIL + || check_for_number_arg(argvars, 1) == FAIL)) + return; + row = (int)tv_get_number_chk(&argvars[0], NULL) - 1; col = (int)tv_get_number_chk(&argvars[1], NULL) - 1; if (row < 0 || row >= screen_Rows @@ -7968,6 +8146,11 @@ f_screenchar(typval_T *argvars, typval_T *rettv) int off; int c; + if (in_vim9script() + && (check_for_number_arg(argvars, 0) == FAIL + || check_for_number_arg(argvars, 1) == FAIL)) + return; + row = (int)tv_get_number_chk(&argvars[0], NULL) - 1; col = (int)tv_get_number_chk(&argvars[1], NULL) - 1; if (row < 0 || row >= screen_Rows || col < 0 || col >= screen_Columns) @@ -7997,6 +8180,12 @@ f_screenchars(typval_T *argvars, typval_T *rettv) if (rettv_list_alloc(rettv) == FAIL) return; + + if (in_vim9script() + && (check_for_number_arg(argvars, 0) == FAIL + || check_for_number_arg(argvars, 1) == FAIL)) + return; + row = (int)tv_get_number_chk(&argvars[0], NULL) - 1; col = (int)tv_get_number_chk(&argvars[1], NULL) - 1; if (row < 0 || row >= screen_Rows || col < 0 || col >= screen_Columns) @@ -8053,6 +8242,11 @@ f_screenstring(typval_T *argvars, typval_T *rettv) rettv->vval.v_string = NULL; rettv->v_type = VAR_STRING; + if (in_vim9script() + && (check_for_number_arg(argvars, 0) == FAIL + || check_for_number_arg(argvars, 1) == FAIL)) + return; + row = (int)tv_get_number_chk(&argvars[0], NULL) - 1; col = (int)tv_get_number_chk(&argvars[1], NULL) - 1; if (row < 0 || row >= screen_Rows || col < 0 || col >= screen_Columns) @@ -8515,6 +8709,9 @@ f_setcharsearch(typval_T *argvars, typval_T *rettv UNUSED) dictitem_T *di; char_u *csearch; + if (in_vim9script() && check_for_dict_arg(argvars, 0) == FAIL) + return; + if (argvars[0].v_type != VAR_DICT) { emsg(_(e_dictreq)); @@ -8593,6 +8790,12 @@ f_setfperm(typval_T *argvars, typval_T *rettv) int mode = 0; rettv->vval.v_number = 0; + + if (in_vim9script() + && (check_for_string_arg(argvars, 0) == FAIL + || check_for_string_arg(argvars, 1) == FAIL)) + return; + fname = tv_get_string_chk(&argvars[0]); if (fname == NULL) return; @@ -8900,6 +9103,9 @@ f_sha256(typval_T *argvars, typval_T *rettv) { char_u *p; + if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL) + return; + p = tv_get_string(&argvars[0]); rettv->vval.v_string = vim_strsave( sha256_bytes(p, (int)STRLEN(p), NULL, 0)); @@ -8934,6 +9140,9 @@ f_shiftwidth(typval_T *argvars UNUSED, typval_T *rettv) { rettv->vval.v_number = 0; + if (in_vim9script() && check_for_opt_number_arg(argvars, 0) == FAIL) + return; + if (argvars[0].v_type != VAR_UNKNOWN) { long col; @@ -8958,6 +9167,9 @@ f_soundfold(typval_T *argvars, typval_T *rettv) { char_u *s; + if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL) + return; + rettv->v_type = VAR_STRING; s = tv_get_string(&argvars[0]); #ifdef FEAT_SPELL @@ -8979,6 +9191,9 @@ f_spellbadword(typval_T *argvars UNUSED, typval_T *rettv) #ifdef FEAT_SPELL int wo_spell_save = curwin->w_p_spell; + if (in_vim9script() && check_for_opt_string_arg(argvars, 0) == FAIL) + return; + if (!curwin->w_p_spell) { did_set_spelllang(curwin); @@ -9298,6 +9513,9 @@ f_substitute(typval_T *argvars, typval_T *rettv) static void f_swapinfo(typval_T *argvars, typval_T *rettv) { + if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL) + return; + if (rettv_dict_alloc(rettv) == OK) get_b0_dict(tv_get_string(argvars), rettv->vval.v_dict); } @@ -9311,6 +9529,10 @@ f_swapname(typval_T *argvars, typval_T *rettv) buf_T *buf; rettv->v_type = VAR_STRING; + + if (in_vim9script() && check_for_buffer_arg(argvars, 0) == FAIL) + return; + buf = tv_get_buf(&argvars[0], FALSE); if (buf == NULL || buf->b_ml.ml_mfp == NULL || buf->b_ml.ml_mfp->mf_fname == NULL) @@ -9460,6 +9682,9 @@ f_synIDtrans(typval_T *argvars UNUSED, typval_T *rettv) int id; #ifdef FEAT_SYN_HL + if (in_vim9script() && check_for_number_arg(argvars, 0) == FAIL) + return; + id = (int)tv_get_number(&argvars[0]); if (id > 0) @@ -9584,6 +9809,9 @@ f_tabpagebuflist(typval_T *argvars UNUSED, typval_T *rettv UNUSED) tabpage_T *tp; win_T *wp = NULL; + if (in_vim9script() && check_for_opt_number_arg(argvars, 0) == FAIL) + return; + if (argvars[0].v_type == VAR_UNKNOWN) wp = firstwin; else @@ -9634,6 +9862,11 @@ f_taglist(typval_T *argvars, typval_T *rettv) char_u *fname = NULL; char_u *tag_pattern; + if (in_vim9script() + && (check_for_string_arg(argvars, 0) == FAIL + || check_for_opt_string_arg(argvars, 1) == FAIL)) + return; + tag_pattern = tv_get_string(&argvars[0]); rettv->vval.v_number = FALSE; @@ -9690,6 +9923,10 @@ f_virtcol(typval_T *argvars, typval_T *rettv) int fnum = curbuf->b_fnum; int len; + if (in_vim9script() + && check_for_string_or_list_arg(argvars, 0) == FAIL) + return; + fp = var2fpos(&argvars[0], FALSE, &fnum, FALSE); if (fp != NULL && fp->lnum <= curbuf->b_ml.ml_line_count && fnum == curbuf->b_fnum) @@ -9718,6 +9955,9 @@ f_visualmode(typval_T *argvars, typval_T *rettv) { char_u str[2]; + if (in_vim9script() && check_for_opt_bool_arg(argvars, 0) == FAIL) + return; + rettv->v_type = VAR_STRING; str[0] = curbuf->b_visual_mode_eval; str[1] = NUL; @@ -9767,6 +10007,11 @@ f_wordcount(typval_T *argvars UNUSED, typval_T *rettv) static void f_xor(typval_T *argvars, typval_T *rettv) { + if (in_vim9script() + && (check_for_number_arg(argvars, 0) == FAIL + || check_for_number_arg(argvars, 1) == FAIL)) + return; + rettv->vval.v_number = tv_get_number_chk(&argvars[0], NULL) ^ tv_get_number_chk(&argvars[1], NULL); } diff --git a/src/evalwindow.c b/src/evalwindow.c index d47680c759..737ca7dbd0 100644 --- a/src/evalwindow.c +++ b/src/evalwindow.c @@ -468,6 +468,9 @@ f_gettabinfo(typval_T *argvars, typval_T *rettv) if (rettv_list_alloc(rettv) != OK) return; + if (in_vim9script() && check_for_opt_number_arg(argvars, 0) == FAIL) + return; + if (argvars[0].v_type != VAR_UNKNOWN) { // Information about one tab page @@ -504,6 +507,9 @@ f_getwininfo(typval_T *argvars, typval_T *rettv) if (rettv_list_alloc(rettv) != OK) return; + if (in_vim9script() && check_for_opt_number_arg(argvars, 0) == FAIL) + return; + if (argvars[0].v_type != VAR_UNKNOWN) { wparg = win_id2wp(tv_get_number(&argvars[0])); @@ -559,6 +565,10 @@ f_getwinpos(typval_T *argvars UNUSED, typval_T *rettv) if (rettv_list_alloc(rettv) == FAIL) return; + + if (in_vim9script() && check_for_opt_number_arg(argvars, 0) == FAIL) + return; + #if defined(FEAT_GUI) \ || (defined(HAVE_TGETENT) && defined(FEAT_TERMRESPONSE)) \ || defined(MSWIN) @@ -624,6 +634,9 @@ f_tabpagenr(typval_T *argvars UNUSED, typval_T *rettv) int nr = 1; char_u *arg; + if (in_vim9script() && check_for_opt_string_arg(argvars, 0) == FAIL) + return; + if (argvars[0].v_type != VAR_UNKNOWN) { arg = tv_get_string_chk(&argvars[0]); @@ -672,9 +685,9 @@ f_tabpagewinnr(typval_T *argvars UNUSED, typval_T *rettv) void f_win_execute(typval_T *argvars, typval_T *rettv) { - int id = (int)tv_get_number(argvars); + int id; tabpage_T *tp; - win_T *wp = win_id2wp_tp(id, &tp); + win_T *wp; win_T *save_curwin; tabpage_T *save_curtab; @@ -682,6 +695,14 @@ f_win_execute(typval_T *argvars, typval_T *rettv) rettv->v_type = VAR_STRING; rettv->vval.v_string = NULL; + if (in_vim9script() + && (check_for_number_arg(argvars, 0) == FAIL + || check_for_string_or_list_arg(argvars, 1) == FAIL + || check_for_opt_string_arg(argvars, 2) == FAIL)) + return; + + id = (int)tv_get_number(argvars); + wp = win_id2wp_tp(id, &tp); if (wp != NULL && tp != NULL) { pos_T curpos = wp->w_cursor; @@ -705,6 +726,9 @@ f_win_execute(typval_T *argvars, typval_T *rettv) void f_win_findbuf(typval_T *argvars, typval_T *rettv) { + if (in_vim9script() && check_for_number_arg(argvars, 0) == FAIL) + return; + if (rettv_list_alloc(rettv) != FAIL) win_findbuf(argvars, rettv->vval.v_list); } @@ -715,6 +739,12 @@ f_win_findbuf(typval_T *argvars, typval_T *rettv) void f_win_getid(typval_T *argvars, typval_T *rettv) { + if (in_vim9script() + && (check_for_opt_number_arg(argvars, 0) == FAIL + || (argvars[0].v_type != VAR_UNKNOWN + && check_for_opt_number_arg(argvars, 1) == FAIL))) + return; + rettv->vval.v_number = win_getid(argvars); } @@ -726,8 +756,12 @@ f_win_gotoid(typval_T *argvars, typval_T *rettv) { win_T *wp; tabpage_T *tp; - int id = tv_get_number(&argvars[0]); + int id; + + if (in_vim9script() && check_for_number_arg(argvars, 0) == FAIL) + return; + id = tv_get_number(&argvars[0]); #ifdef FEAT_CMDWIN if (cmdwin_type != 0) { @@ -750,6 +784,9 @@ f_win_gotoid(typval_T *argvars, typval_T *rettv) void f_win_id2tabwin(typval_T *argvars, typval_T *rettv) { + if (in_vim9script() && check_for_number_arg(argvars, 0) == FAIL) + return; + if (rettv_list_alloc(rettv) != FAIL) win_id2tabwin(argvars, rettv->vval.v_list); } @@ -760,6 +797,9 @@ f_win_id2tabwin(typval_T *argvars, typval_T *rettv) void f_win_id2win(typval_T *argvars, typval_T *rettv) { + if (in_vim9script() && check_for_number_arg(argvars, 0) == FAIL) + return; + rettv->vval.v_number = win_id2win(argvars); } @@ -774,6 +814,9 @@ f_win_screenpos(typval_T *argvars, typval_T *rettv) if (rettv_list_alloc(rettv) == FAIL) return; + if (in_vim9script() && check_for_number_arg(argvars, 0) == FAIL) + return; + wp = find_win_by_nr_or_id(&argvars[0]); list_append_number(rettv->vval.v_list, wp == NULL ? 0 : wp->w_winrow + 1); list_append_number(rettv->vval.v_list, wp == NULL ? 0 : wp->w_wincol + 1); @@ -883,6 +926,10 @@ f_win_gettype(typval_T *argvars, typval_T *rettv) rettv->v_type = VAR_STRING; rettv->vval.v_string = NULL; + + if (in_vim9script() && check_for_opt_number_arg(argvars, 0) == FAIL) + return; + if (argvars[0].v_type != VAR_UNKNOWN) { wp = find_win_by_nr_or_id(&argvars[0]); @@ -934,6 +981,9 @@ f_winbufnr(typval_T *argvars, typval_T *rettv) { win_T *wp; + if (in_vim9script() && check_for_number_arg(argvars, 0) == FAIL) + return; + wp = find_win_by_nr_or_id(&argvars[0]); if (wp == NULL) rettv->vval.v_number = -1; @@ -959,6 +1009,9 @@ f_winheight(typval_T *argvars, typval_T *rettv) { win_T *wp; + if (in_vim9script() && check_for_number_arg(argvars, 0) == FAIL) + return; + wp = find_win_by_nr_or_id(&argvars[0]); if (wp == NULL) rettv->vval.v_number = -1; @@ -977,6 +1030,9 @@ f_winlayout(typval_T *argvars, typval_T *rettv) if (rettv_list_alloc(rettv) != OK) return; + if (in_vim9script() && check_for_opt_number_arg(argvars, 0) == FAIL) + return; + if (argvars[0].v_type == VAR_UNKNOWN) tp = curtab; else @@ -1007,6 +1063,9 @@ f_winnr(typval_T *argvars UNUSED, typval_T *rettv) { int nr = 1; + if (in_vim9script() && check_for_opt_string_arg(argvars, 0) == FAIL) + return; + nr = get_winnr(curtab, &argvars[0]); rettv->vval.v_number = nr; } @@ -1052,6 +1111,9 @@ f_winrestview(typval_T *argvars, typval_T *rettv UNUSED) { dict_T *dict; + if (in_vim9script() && check_for_dict_arg(argvars, 0) == FAIL) + return; + if (argvars[0].v_type != VAR_DICT || (dict = argvars[0].vval.v_dict) == NULL) emsg(_(e_invarg)); @@ -1129,6 +1191,9 @@ f_winwidth(typval_T *argvars, typval_T *rettv) { win_T *wp; + if (in_vim9script() && check_for_number_arg(argvars, 0) == FAIL) + return; + wp = find_win_by_nr_or_id(&argvars[0]); if (wp == NULL) rettv->vval.v_number = -1; diff --git a/src/ex_docmd.c b/src/ex_docmd.c index 2f1fdb6045..fbfba52dd4 100644 --- a/src/ex_docmd.c +++ b/src/ex_docmd.c @@ -3808,11 +3808,16 @@ cmd_exists(char_u *name) f_fullcommand(typval_T *argvars, typval_T *rettv) { exarg_T ea; - char_u *name = argvars[0].vval.v_string; + char_u *name; char_u *p; rettv->v_type = VAR_STRING; rettv->vval.v_string = NULL; + + if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL) + return; + + name = argvars[0].vval.v_string; if (name == NULL) return; diff --git a/src/ex_getln.c b/src/ex_getln.c index 40b8886a04..ad0f07e3fb 100644 --- a/src/ex_getln.c +++ b/src/ex_getln.c @@ -4061,8 +4061,12 @@ set_cmdline_pos( void f_setcmdpos(typval_T *argvars, typval_T *rettv) { - int pos = (int)tv_get_number(&argvars[0]) - 1; + int pos; + if (in_vim9script() && check_for_number_arg(argvars, 0) == FAIL) + return; + + pos = (int)tv_get_number(&argvars[0]) - 1; if (pos >= 0) rettv->vval.v_number = set_cmdline_pos(pos); } @@ -4517,7 +4521,7 @@ get_user_input( int inputdialog, int secret) { - char_u *prompt = tv_get_string_chk(&argvars[0]); + char_u *prompt; char_u *p = NULL; int c; char_u buf[NUMBUFLEN]; @@ -4531,6 +4535,15 @@ get_user_input( if (input_busy) return; // this doesn't work recursively. + if (in_vim9script() + && (check_for_string_arg(argvars, 0) == FAIL + || check_for_opt_string_arg(argvars, 1) == FAIL + || (argvars[1].v_type != VAR_UNKNOWN + && check_for_opt_string_arg(argvars, 2) == FAIL))) + return; + + prompt = tv_get_string_chk(&argvars[0]); + #ifdef NO_CONSOLE_INPUT // While starting up, there is no place to enter text. When running tests // with --not-a-term we assume feedkeys() will be used. diff --git a/src/filepath.c b/src/filepath.c index 989f56e537..74ee2ec15a 100644 --- a/src/filepath.c +++ b/src/filepath.c @@ -834,6 +834,11 @@ f_delete(typval_T *argvars, typval_T *rettv) if (check_restricted() || check_secure()) return; + if (in_vim9script() + && (check_for_string_arg(argvars, 0) == FAIL + || check_for_opt_string_arg(argvars, 1) == FAIL)) + return; + name = tv_get_string(&argvars[0]); if (name == NULL || *name == NUL) { @@ -899,6 +904,7 @@ f_filereadable(typval_T *argvars, typval_T *rettv) if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL) return; + #ifndef O_NONBLOCK # define O_NONBLOCK 0 #endif @@ -946,7 +952,11 @@ findfilendir( rettv->vval.v_string = NULL; rettv->v_type = VAR_STRING; - if (in_vim9script() && check_for_nonempty_string_arg(argvars, 0) == FAIL) + if (in_vim9script() + && (check_for_nonempty_string_arg(argvars, 0) == FAIL + || check_for_opt_string_arg(argvars, 1) == FAIL + || (argvars[1].v_type != VAR_UNKNOWN + && check_for_opt_number_arg(argvars, 2) == FAIL))) return; #ifdef FEAT_SEARCHPATH @@ -1027,9 +1037,11 @@ f_fnamemodify(typval_T *argvars, typval_T *rettv) char_u *fbuf = NULL; char_u buf[NUMBUFLEN]; - if (in_vim9script() && (check_for_string_arg(argvars, 0) == FAIL - || check_for_string_arg(argvars, 1) == FAIL)) + if (in_vim9script() + && (check_for_string_arg(argvars, 0) == FAIL + || check_for_string_arg(argvars, 1) == FAIL)) return; + fname = tv_get_string_chk(&argvars[0]); mods = tv_get_string_buf_chk(&argvars[1], buf); if (mods == NULL || fname == NULL) @@ -1077,6 +1089,12 @@ f_getcwd(typval_T *argvars, typval_T *rettv) rettv->v_type = VAR_STRING; rettv->vval.v_string = NULL; + if (in_vim9script() + && (check_for_opt_number_arg(argvars, 0) == FAIL + || (argvars[0].v_type != VAR_UNKNOWN + && check_for_opt_number_arg(argvars, 1) == FAIL))) + return; + if (argvars[0].v_type == VAR_NUMBER && argvars[0].vval.v_number == -1 && argvars[1].v_type == VAR_UNKNOWN) @@ -1141,6 +1159,7 @@ f_getfperm(typval_T *argvars, typval_T *rettv) if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL) return; + fname = tv_get_string(&argvars[0]); rettv->v_type = VAR_STRING; @@ -1190,6 +1209,7 @@ f_getftime(typval_T *argvars, typval_T *rettv) if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL) return; + fname = tv_get_string(&argvars[0]); if (mch_stat((char *)fname, &st) >= 0) rettv->vval.v_number = (varnumber_T)st.st_mtime; @@ -1236,6 +1256,7 @@ f_getftype(typval_T *argvars, typval_T *rettv) if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL) return; + fname = tv_get_string(&argvars[0]); rettv->v_type = VAR_STRING; @@ -1311,9 +1332,12 @@ f_glob(typval_T *argvars, typval_T *rettv) f_glob2regpat(typval_T *argvars, typval_T *rettv) { char_u buf[NUMBUFLEN]; - char_u *pat = tv_get_string_buf_chk_strict(&argvars[0], buf, - in_vim9script()); + char_u *pat; + + if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL) + return; + pat = tv_get_string_buf_chk_strict(&argvars[0], buf, in_vim9script()); rettv->v_type = VAR_STRING; rettv->vval.v_string = (pat == NULL) ? NULL : file_pat_to_reg_pat(pat, NULL, NULL, FALSE); @@ -1382,6 +1406,9 @@ f_globpath(typval_T *argvars, typval_T *rettv) void f_isdirectory(typval_T *argvars, typval_T *rettv) { + if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL) + return; + rettv->vval.v_number = mch_isdir(tv_get_string(&argvars[0])); } @@ -1429,6 +1456,13 @@ f_mkdir(typval_T *argvars, typval_T *rettv) if (check_restricted() || check_secure()) return; + if (in_vim9script() + && (check_for_nonempty_string_arg(argvars, 0) == FAIL + || check_for_opt_string_arg(argvars, 1) == FAIL + || (argvars[1].v_type != VAR_UNKNOWN + && check_for_opt_number_arg(argvars, 2) == FAIL))) + return; + dir = tv_get_string_buf(&argvars[0], buf); if (*dir == NUL) return; @@ -1919,6 +1953,9 @@ read_file_or_blob(typval_T *argvars, typval_T *rettv, int always_blob) void f_readblob(typval_T *argvars, typval_T *rettv) { + if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL) + return; + read_file_or_blob(argvars, rettv, TRUE); } @@ -1928,6 +1965,13 @@ f_readblob(typval_T *argvars, typval_T *rettv) void f_readfile(typval_T *argvars, typval_T *rettv) { + if (in_vim9script() + && (check_for_nonempty_string_arg(argvars, 0) == FAIL + || check_for_opt_string_arg(argvars, 1) == FAIL + || (argvars[1].v_type != VAR_UNKNOWN + && check_for_opt_number_arg(argvars, 2) == FAIL))) + return; + read_file_or_blob(argvars, rettv, FALSE); } @@ -1942,6 +1986,9 @@ f_resolve(typval_T *argvars, typval_T *rettv) char_u *buf = NULL; #endif + if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL) + return; + p = tv_get_string(&argvars[0]); #ifdef FEAT_SHORTCUT { @@ -2497,6 +2544,11 @@ f_browsedir(typval_T *argvars UNUSED, typval_T *rettv) char_u *initdir; char_u buf[NUMBUFLEN]; + if (in_vim9script() + && (check_for_string_arg(argvars, 0) == FAIL + || check_for_string_arg(argvars, 1) == FAIL)) + return; + title = tv_get_string_chk(&argvars[0]); initdir = tv_get_string_buf_chk(&argvars[1], buf); diff --git a/src/findfile.c b/src/findfile.c index 7c2a61f4ae..b79b1d1dbf 100644 --- a/src/findfile.c +++ b/src/findfile.c @@ -2857,6 +2857,9 @@ f_simplify(typval_T *argvars, typval_T *rettv) { char_u *p; + if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL) + return; + p = tv_get_string_strict(&argvars[0]); rettv->vval.v_string = vim_strsave(p); simplify_filename(rettv->vval.v_string); // simplify in place diff --git a/src/float.c b/src/float.c index 7c020448aa..898095fd4b 100644 --- a/src/float.c +++ b/src/float.c @@ -82,6 +82,9 @@ get_float_arg(typval_T *argvars, float_T *f) void f_abs(typval_T *argvars, typval_T *rettv) { + if (in_vim9script() && check_for_float_or_nr_arg(argvars, 0) == FAIL) + return; + if (argvars[0].v_type == VAR_FLOAT) { rettv->v_type = VAR_FLOAT; @@ -110,6 +113,9 @@ f_acos(typval_T *argvars, typval_T *rettv) { float_T f = 0.0; + if (in_vim9script() && check_for_float_or_nr_arg(argva