To: vim_dev@googlegroups.com Subject: Patch 8.2.2434 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.2434 Problem: Vim9: no error when compiling str2nr() with a number. Solution: Add argument type checks. (closes #7759) Files: src/evalfunc.c, src/typval.c, src/proto/typval.pro, src/testdir/test_vim9_builtin.vim *** ../vim-8.2.2433/src/evalfunc.c 2021-01-26 22:42:17.690836814 +0100 --- src/evalfunc.c 2021-01-30 22:57:14.896393338 +0100 *************** *** 331,336 **** --- 331,348 ---- } /* + * Check "type" is a bool or number 0 or 1. + */ + static int + arg_bool(type_T *type, argcontext_T *context) + { + if (type->tt_type == VAR_ANY + || type->tt_type == VAR_NUMBER || type->tt_type == VAR_BOOL) + return OK; + return check_arg_type(&t_bool, type, context); + } + + /* * Check "type" is a list or a blob. */ static int *************** *** 423,428 **** --- 435,441 ---- /* * Lists of functions that check the argument types of a builtin function. */ + argcheck_T arg3_string_nr_bool[] = {arg_string, arg_number, arg_bool}; argcheck_T arg1_float_or_nr[] = {arg_float_or_nr}; argcheck_T arg2_listblob_item[] = {arg_list_or_blob, arg_item_of_prev}; argcheck_T arg23_extend[] = {arg_list_or_dict, arg_same_as_prev, arg_extend3}; *************** *** 1552,1558 **** ret_float, FLOAT_FUNC(f_str2float)}, {"str2list", 1, 2, FEARG_1, NULL, ret_list_number, f_str2list}, ! {"str2nr", 1, 3, FEARG_1, NULL, ret_number, f_str2nr}, {"strcharpart", 2, 3, FEARG_1, NULL, ret_string, f_strcharpart}, --- 1565,1571 ---- ret_float, FLOAT_FUNC(f_str2float)}, {"str2list", 1, 2, FEARG_1, NULL, ret_list_number, f_str2list}, ! {"str2nr", 1, 3, FEARG_1, arg3_string_nr_bool, ret_number, f_str2nr}, {"strcharpart", 2, 3, FEARG_1, NULL, ret_string, f_strcharpart}, *************** *** 9076,9082 **** what |= STR2NR_QUOTE; } ! p = skipwhite(tv_get_string(&argvars[0])); isneg = (*p == '-'); if (*p == '+' || *p == '-') p = skipwhite(p + 1); --- 9089,9095 ---- what |= STR2NR_QUOTE; } ! p = skipwhite(tv_get_string_strict(&argvars[0])); isneg = (*p == '-'); if (*p == '+' || *p == '-') p = skipwhite(p + 1); *** ../vim-8.2.2433/src/typval.c 2021-01-10 20:22:20.767926906 +0100 --- src/typval.c 2021-01-30 22:59:11.863880885 +0100 *************** *** 388,393 **** --- 388,406 ---- return tv_get_string_buf(varp, mybuf); } + /* + * Like tv_get_string() but don't allow number to string conversion for Vim9. + */ + char_u * + tv_get_string_strict(typval_T *varp) + { + static char_u mybuf[NUMBUFLEN]; + char_u *res = tv_get_string_buf_chk_strict( + varp, mybuf, in_vim9script()); + + return res != NULL ? res : (char_u *)""; + } + char_u * tv_get_string_buf(typval_T *varp, char_u *buf) { *************** *** 410,418 **** --- 423,442 ---- char_u * tv_get_string_buf_chk(typval_T *varp, char_u *buf) { + return tv_get_string_buf_chk_strict(varp, buf, FALSE); + } + + char_u * + tv_get_string_buf_chk_strict(typval_T *varp, char_u *buf, int strict) + { switch (varp->v_type) { case VAR_NUMBER: + if (strict) + { + emsg(_(e_using_number_as_string)); + break; + } vim_snprintf((char *)buf, NUMBUFLEN, "%lld", (varnumber_T)varp->vval.v_number); return buf; *** ../vim-8.2.2433/src/proto/typval.pro 2021-01-09 15:45:20.353451132 +0100 --- src/proto/typval.pro 2021-01-30 22:58:47.303987356 +0100 *************** *** 12,20 **** --- 12,22 ---- int check_for_string(typval_T *tv); int check_for_nonempty_string(typval_T *tv); char_u *tv_get_string(typval_T *varp); + char_u *tv_get_string_strict(typval_T *varp); char_u *tv_get_string_buf(typval_T *varp, char_u *buf); char_u *tv_get_string_chk(typval_T *varp); char_u *tv_get_string_buf_chk(typval_T *varp, char_u *buf); + char_u *tv_get_string_buf_chk_strict(typval_T *varp, char_u *buf, int strict); char_u *tv_stringify(typval_T *varp, char_u *buf); int tv_check_lock(typval_T *tv, char_u *name, int use_gettext); void copy_tv(typval_T *from, typval_T *to); *** ../vim-8.2.2433/src/testdir/test_vim9_builtin.vim 2021-01-22 22:31:06.676005413 +0100 --- src/testdir/test_vim9_builtin.vim 2021-01-30 23:04:50.042460293 +0100 *************** *** 867,872 **** --- 867,879 ---- def Test_str2nr() str2nr("1'000'000", 10, true)->assert_equal(1000000) + + CheckDefFailure(['echo str2nr(123)'], 'E1013:') + CheckScriptFailure(['vim9script', 'echo str2nr(123)'], 'E1024:') + CheckDefFailure(['echo str2nr("123", "x")'], 'E1013:') + CheckScriptFailure(['vim9script', 'echo str2nr("123", "x")'], 'E1030:') + CheckDefFailure(['echo str2nr("123", 10, "x")'], 'E1013:') + CheckScriptFailure(['vim9script', 'echo str2nr("123", 10, "x")'], 'E1135:') enddef def Test_strchars() *** ../vim-8.2.2433/src/version.c 2021-01-30 21:40:00.155043125 +0100 --- src/version.c 2021-01-30 22:43:08.624914971 +0100 *************** *** 752,753 **** --- 752,755 ---- { /* Add new patch number below this line */ + /**/ + 2434, /**/ -- There is a fine line between courage and foolishness. Unfortunately, it's not a fence. /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///