To: vim_dev@googlegroups.com Subject: Patch 8.2.3650 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.3650 Problem: Vim9: for loop variable can be a list member. Solution: Check for valid variable name. (closes #9179) Files: src/vim9compile.c, src/dict.c, src/eval.c, src/evalvars.c, src/proto/evalvars.pro, src/testdir/test_vim9_script.vim *** ../vim-8.2.3649/src/vim9compile.c 2021-10-23 13:32:27.227954893 +0100 --- src/vim9compile.c 2021-11-22 19:59:44.878225260 +0000 *************** *** 8220,8227 **** for (idx = 0; idx < var_count; ++idx) { assign_dest_T dest = dest_local; ! int opt_flags = 0; ! int vimvaridx = -1; type_T *type = &t_any; type_T *lhs_type = &t_any; where_T where = WHERE_INIT; --- 8220,8227 ---- for (idx = 0; idx < var_count; ++idx) { assign_dest_T dest = dest_local; ! int opt_flags = 0; ! int vimvaridx = -1; type_T *type = &t_any; type_T *lhs_type = &t_any; where_T where = WHERE_INIT; *************** *** 8255,8260 **** --- 8255,8262 ---- } else { + if (!valid_varname(arg, varlen, FALSE)) + goto failed; if (lookup_local(arg, varlen, NULL, cctx) == OK) { semsg(_(e_variable_already_declared), arg); *** ../vim-8.2.3649/src/dict.c 2021-09-06 18:19:41.595784061 +0100 --- src/dict.c 2021-11-22 19:59:54.738242512 +0000 *************** *** 1102,1108 **** && HI2DI(hi2)->di_tv.v_type == VAR_FUNC && var_wrong_func_name(hi2->hi_key, di1 == NULL)) break; ! if (!valid_varname(hi2->hi_key, TRUE)) break; } --- 1102,1108 ---- && HI2DI(hi2)->di_tv.v_type == VAR_FUNC && var_wrong_func_name(hi2->hi_key, di1 == NULL)) break; ! if (!valid_varname(hi2->hi_key, -1, TRUE)) break; } *** ../vim-8.2.3649/src/eval.c 2021-10-23 13:32:27.223954845 +0100 --- src/eval.c 2021-11-22 20:00:07.810264598 +0000 *************** *** 1128,1134 **** wrong = (lp->ll_dict->dv_scope == VAR_DEF_SCOPE && rettv->v_type == VAR_FUNC && var_wrong_func_name(key, lp->ll_di == NULL)) ! || !valid_varname(key, TRUE); if (len != -1) key[len] = prevval; if (wrong) --- 1128,1134 ---- wrong = (lp->ll_dict->dv_scope == VAR_DEF_SCOPE && rettv->v_type == VAR_FUNC && var_wrong_func_name(key, lp->ll_di == NULL)) ! || !valid_varname(key, -1, TRUE); if (len != -1) key[len] = prevval; if (wrong) *** ../vim-8.2.3649/src/evalvars.c 2021-11-20 19:13:35.945146370 +0000 --- src/evalvars.c 2021-11-22 20:01:39.798396107 +0000 *************** *** 3431,3437 **** // Make sure the variable name is valid. In Vim9 script an autoload // variable must be prefixed with "g:". ! if (!valid_varname(varname, !vim9script || STRNCMP(name, "g:", 2) == 0)) goto failed; --- 3431,3437 ---- // Make sure the variable name is valid. In Vim9 script an autoload // variable must be prefixed with "g:". ! if (!valid_varname(varname, -1, !vim9script || STRNCMP(name, "g:", 2) == 0)) goto failed; *************** *** 3631,3644 **** /* * Check if a variable name is valid. When "autoload" is true "#" is allowed. * Return FALSE and give an error if not. */ int ! valid_varname(char_u *varname, int autoload) { char_u *p; ! for (p = varname; *p != NUL; ++p) if (!eval_isnamec1(*p) && (p == varname || !VIM_ISDIGIT(*p)) && !(autoload && *p == AUTOLOAD_CHAR)) { --- 3631,3645 ---- /* * Check if a variable name is valid. When "autoload" is true "#" is allowed. + * If "len" is -1 use all of "varname", otherwise up to "varname[len]". * Return FALSE and give an error if not. */ int ! valid_varname(char_u *varname, int len, int autoload) { char_u *p; ! for (p = varname; len < 0 ? *p != NUL : p < varname + len; ++p) if (!eval_isnamec1(*p) && (p == varname || !VIM_ISDIGIT(*p)) && !(autoload && *p == AUTOLOAD_CHAR)) { *** ../vim-8.2.3649/src/proto/evalvars.pro 2021-04-19 19:49:58.156857538 +0100 --- src/proto/evalvars.pro 2021-11-22 20:01:59.606419356 +0000 *************** *** 78,84 **** int var_check_fixed(int flags, char_u *name, int use_gettext); int var_wrong_func_name(char_u *name, int new_var); int value_check_lock(int lock, char_u *name, int use_gettext); ! int valid_varname(char_u *varname, int autoload); void reset_v_option_vars(void); void assert_error(garray_T *gap); int var_exists(char_u *var); --- 78,84 ---- int var_check_fixed(int flags, char_u *name, int use_gettext); int var_wrong_func_name(char_u *name, int new_var); int value_check_lock(int lock, char_u *name, int use_gettext); ! int valid_varname(char_u *varname, int len, int autoload); void reset_v_option_vars(void); void assert_error(garray_T *gap); int var_exists(char_u *var); *** ../vim-8.2.3649/src/testdir/test_vim9_script.vim 2021-11-22 18:30:59.651943916 +0000 --- src/testdir/test_vim9_script.vim 2021-11-22 20:08:15.486609974 +0000 *************** *** 2865,2875 **** endfor END CheckDefExecAndScriptFailure(lines, 'E1012: Type mismatch; expected job but got string', 2) enddef def Test_for_loop_script_var() # cannot use s:var in a :def function ! CheckDefFailure(['for s:var in range(3)', 'echo 3'], 'E1101:') # can use s:var in Vim9 script, with or without s: var lines =<< trim END --- 2865,2899 ---- endfor END CheckDefExecAndScriptFailure(lines, 'E1012: Type mismatch; expected job but got string', 2) + + lines =<< trim END + var i = 0 + for i in [1, 2, 3] + echo i + endfor + END + CheckDefExecAndScriptFailure2(lines, 'E1017:', 'E1041:') + + lines =<< trim END + var l = [0] + for l[0] in [1, 2, 3] + echo l[0] + endfor + END + CheckDefExecAndScriptFailure2(lines, 'E461:', 'E1017:') + + lines =<< trim END + var d = {x: 0} + for d.x in [1, 2, 3] + echo d.x + endfor + END + CheckDefExecAndScriptFailure2(lines, 'E461:', 'E1017:') enddef def Test_for_loop_script_var() # cannot use s:var in a :def function ! CheckDefFailure(['for s:var in range(3)', 'echo 3'], 'E461:') # can use s:var in Vim9 script, with or without s: var lines =<< trim END *** ../vim-8.2.3649/src/version.c 2021-11-22 18:30:59.651943916 +0000 --- src/version.c 2021-11-22 19:59:22.190183484 +0000 *************** *** 759,760 **** --- 759,762 ---- { /* Add new patch number below this line */ + /**/ + 3650, /**/ -- BRIDGEKEEPER: What is your favorite editor? GAWAIN: Emacs ... No, Viiiiiiiiiiimmmmmmm! "Monty Python and the Holy editor wars" PYTHON (MONTY) SOFTWARE LTD /// 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 ///