# HG changeset patch # User Bram Moolenaar # Date 1640638804 -3600 # Node ID 2df40c348c70172d59ef3f2f4df0cfa6cc8a98e0 # Parent 73cedd119ce2c2d16a1d9d6560a0ec2411ce45a0 patch 8.2.3916: no error for passing an invalid line number to append() Commit: https://github.com/vim/vim/commit/8dac2acd6a79d571ff5409d9c90b4c9e73237eb4 Author: Bram Moolenaar Date: Mon Dec 27 20:57:06 2021 +0000 patch 8.2.3916: no error for passing an invalid line number to append() Problem: No error for passing an invalid line number to append(). Solution: In Vim9 script check for a non-negative number. (closes https://github.com/vim/vim/issues/9417) diff --git a/src/errors.h b/src/errors.h --- a/src/errors.h +++ b/src/errors.h @@ -357,6 +357,10 @@ EXTERN char e_using_invalid_value_as_str EXTERN char e_cannot_index_special_variable[] INIT(= N_("E909: Cannot index a special variable")); #endif +EXTERN char_u e_invalid_column_number_nr[] + INIT(= N_("E964: Invalid column number: %ld")); +EXTERN char_u e_invalid_line_number_nr[] + INIT(= N_("E966: Invalid line number: %ld")); EXTERN char e_command_not_supported_in_vim9_script_missing_var_str[] INIT(= N_("E1100: Command not supported in Vim9 script (missing :var?): %s")); #ifdef FEAT_EVAL diff --git a/src/eval.c b/src/eval.c --- a/src/eval.c +++ b/src/eval.c @@ -5359,8 +5359,9 @@ var2fpos( name = tv_get_string_chk(varp); if (name == NULL) return NULL; - if (name[0] == '.') // cursor + if (name[0] == '.' && (!in_vim9script() || name[1] == NUL)) { + // cursor pos = curwin->w_cursor; if (charcol) pos.col = buf_byteidx_to_charidx(curbuf, pos.lnum, pos.col); @@ -5376,8 +5377,10 @@ var2fpos( pos.col = buf_byteidx_to_charidx(curbuf, pos.lnum, pos.col); return &pos; } - if (name[0] == '\'') // mark + if (name[0] == '\'' && (!in_vim9script() + || (name[1] != NUL && name[2] == NUL))) { + // mark pp = getmark_buf_fnum(curbuf, name[1], FALSE, fnum); if (pp == NULL || pp == (pos_T *)-1 || pp->lnum <= 0) return NULL; diff --git a/src/evalbuffer.c b/src/evalbuffer.c --- a/src/evalbuffer.c +++ b/src/evalbuffer.c @@ -151,6 +151,8 @@ set_buffer_lines( if (buf == NULL || (!is_curbuf && buf->b_ml.ml_mfp == NULL) || lnum < 1) { rettv->vval.v_number = 1; // FAIL + if (in_vim9script() && lnum < 1) + semsg(_(e_invalid_line_number_nr), lnum_arg); return; } diff --git a/src/indent.c b/src/indent.c --- a/src/indent.c +++ b/src/indent.c @@ -2130,7 +2130,11 @@ f_indent(typval_T *argvars, typval_T *re if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) rettv->vval.v_number = get_indent_lnum(lnum); else + { + if (in_vim9script()) + semsg(_(e_invalid_line_number_nr), lnum); rettv->vval.v_number = -1; + } } /* @@ -2154,6 +2158,8 @@ f_lispindent(typval_T *argvars UNUSED, t rettv->vval.v_number = get_lisp_indent(); curwin->w_cursor = pos; } + else if (in_vim9script()) + semsg(_(e_invalid_line_number_nr), lnum); else #endif rettv->vval.v_number = -1; diff --git a/src/testdir/test_vim9_builtin.vim b/src/testdir/test_vim9_builtin.vim --- a/src/testdir/test_vim9_builtin.vim +++ b/src/testdir/test_vim9_builtin.vim @@ -182,6 +182,9 @@ def Test_append() assert_equal("function('min')", getline(1)) CheckDefAndScriptFailure(['append([1], "x")'], ['E1013: Argument 1: type mismatch, expected string but got list', 'E1220: String or Number required for argument 1']) CheckDefExecAndScriptFailure(['append("", "x")'], 'E1209: Invalid value for a line number') + CheckDefExecAndScriptFailure(['append(".a", "x")'], 'E1209: Invalid value for a line number') + CheckDefExecAndScriptFailure(['append("''aa", "x")'], 'E1209: Invalid value for a line number') + CheckDefExecAndScriptFailure(['append(-1, "x")'], 'E966: Invalid line number: -1') bwipe! enddef @@ -199,6 +202,7 @@ def Test_appendbufline() assert_equal(['zero'], getbufline(bnum, 1)) CheckDefAndScriptFailure(['appendbufline([1], 1, "x")'], ['E1013: Argument 1: type mismatch, expected string but got list', 'E1220: String or Number required for argument 1']) CheckDefAndScriptFailure(['appendbufline(1, [1], "x")'], ['E1013: Argument 2: type mismatch, expected string but got list', 'E1220: String or Number required for argument 2']) + CheckDefExecAndScriptFailure(['appendbufline(' .. bnum .. ', -1, "x")'], 'E966: Invalid line number: -1') CheckDefAndScriptFailure(['appendbufline(1, 1, {"a": 10})'], ['E1013: Argument 3: type mismatch, expected string but got dict', 'E1224: String, Number or List required for argument 3']) bnum->bufwinid()->win_gotoid() appendbufline('', 0, 'numbers') @@ -1834,6 +1838,7 @@ def Test_indent() CheckDefAndScriptFailure(['indent([1])'], ['E1013: Argument 1: type mismatch, expected string but got list', 'E1220: String or Number required for argument 1']) CheckDefAndScriptFailure(['indent(true)'], ['E1013: Argument 1: type mismatch, expected string but got bool', 'E1220: String or Number required for argument 1']) CheckDefExecAndScriptFailure(['indent("")'], 'E1209: Invalid value for a line number') + CheckDefExecAndScriptFailure(['indent(-1)'], 'E966: Invalid line number: -1') assert_equal(0, indent(1)) enddef @@ -2061,6 +2066,7 @@ enddef def Test_lispindent() CheckDefAndScriptFailure(['lispindent({})'], ['E1013: Argument 1: type mismatch, expected string but got dict', 'E1220: String or Number required for argument 1']) CheckDefExecAndScriptFailure(['lispindent("")'], 'E1209: Invalid value for a line number') + CheckDefExecAndScriptFailure(['lispindent(-1)'], 'E966: Invalid line number: -1') assert_equal(0, lispindent(1)) enddef @@ -3239,6 +3245,7 @@ def Test_setbufline() assert_equal(['1', '2', '3', 'one', '10', 'two', '11'], getbufline(bnum, 1, '$')) CheckDefAndScriptFailure(['setbufline([1], 1, "x")'], ['E1013: Argument 1: type mismatch, expected string but got list', 'E1220: String or Number required for argument 1']) CheckDefAndScriptFailure(['setbufline(1, [1], "x")'], ['E1013: Argument 2: type mismatch, expected string but got list', 'E1220: String or Number required for argument 2']) + CheckDefExecAndScriptFailure(['setbufline(' .. bnum .. ', -1, "x")'], 'E966: Invalid line number: -1') CheckDefAndScriptFailure(['setbufline(1, 1, {"a": 10})'], ['E1013: Argument 3: type mismatch, expected string but got dict', 'E1224: String, Number or List required for argument 3']) bnum->bufwinid()->win_gotoid() setbufline('', 1, 'nombres') @@ -3303,6 +3310,7 @@ def Test_setline() assert_equal(['10', 'b', 'c', 'd'], getline(1, '$')) CheckDefAndScriptFailure(['setline([1], "x")'], ['E1013: Argument 1: type mismatch, expected string but got list', 'E1220: String or Number required for argument 1']) CheckDefExecAndScriptFailure(['setline("", "x")'], 'E1209: Invalid value for a line number') + CheckDefExecAndScriptFailure(['setline(-1, "x")'], 'E966: Invalid line number: -1') bw! enddef diff --git a/src/textprop.c b/src/textprop.c --- a/src/textprop.c +++ b/src/textprop.c @@ -48,8 +48,6 @@ static hashtab_T *global_proptypes = NUL static int proptype_id = 0; static char_u e_type_not_exist[] = N_("E971: Property type %s does not exist"); -static char_u e_invalid_col[] = N_("E964: Invalid column number: %ld"); -static char_u e_invalid_lnum[] = N_("E966: Invalid line number: %ld"); /* * Find a property type by name, return the hashitem. @@ -169,7 +167,7 @@ f_prop_add(typval_T *argvars, typval_T * start_col = tv_get_number(&argvars[1]); if (start_col < 1) { - semsg(_(e_invalid_col), (long)start_col); + semsg(_(e_invalid_column_number_nr), (long)start_col); return; } if (argvars[2].v_type != VAR_DICT) @@ -213,12 +211,12 @@ prop_add_one( if (start_lnum < 1 || start_lnum > buf->b_ml.ml_line_count) { - semsg(_(e_invalid_lnum), (long)start_lnum); + semsg(_(e_invalid_line_number_nr), (long)start_lnum); return FAIL; } if (end_lnum < start_lnum || end_lnum > buf->b_ml.ml_line_count) { - semsg(_(e_invalid_lnum), (long)end_lnum); + semsg(_(e_invalid_line_number_nr), (long)end_lnum); return FAIL; } @@ -243,7 +241,7 @@ prop_add_one( col = 1; if (col - 1 > (colnr_T)textlen) { - semsg(_(e_invalid_col), (long)start_col); + semsg(_(e_invalid_column_number_nr), (long)start_col); return FAIL; } diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -750,6 +750,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 3916, +/**/ 3915, /**/ 3914,