Patch 9.0.0742

5 views
Skip to first unread message

Bram Moolenaar

unread,
Oct 13, 2022, 11:13:56 AM10/13/22
to vim...@googlegroups.com

Patch 9.0.0742
Problem: Reading past end of the line when compiling a function with
errors.
Solution: Do not return an invalid pointer. Fix skipping redirection.
Files: src/vim9compile.c, src/vim9cmds.c, src/testdir/test_vim9_func.vim,
src/testdir/test_vim9_script.vim


*** ../vim-9.0.0741/src/vim9compile.c 2022-10-11 20:04:05.880795466 +0100
--- src/vim9compile.c 2022-10-13 16:11:09.580587352 +0100
***************
*** 1284,1289 ****
--- 1284,1302 ----
}

/*
+ * Return TRUE if "name" is a valid register to use.
+ * Return FALSE and give an error message if not.
+ */
+ static int
+ valid_dest_reg(int name)
+ {
+ if ((name == '@' || valid_yank_reg(name, FALSE)) && name != '.')
+ return TRUE;
+ emsg_invreg(name);
+ return FAIL;
+ }
+
+ /*
* For one assignment figure out the type of destination. Return it in "dest".
* When not recognized "dest" is not set.
* For an option "option_scope" is set.
***************
*** 1364,1375 ****
}
else if (*name == '@')
{
! if (name[1] != '@'
! && (!valid_yank_reg(name[1], FALSE) || name[1] == '.'))
! {
! emsg_invreg(name[1]);
return FAIL;
- }
*dest = dest_reg;
*type = name[1] == '#' ? &t_number_or_string : &t_string;
}
--- 1377,1384 ----
}
else if (*name == '@')
{
! if (!valid_dest_reg(name[1]))
return FAIL;
*dest = dest_reg;
*type = name[1] == '#' ? &t_number_or_string : &t_string;
}
***************
*** 1445,1451 ****
--- 1454,1464 ----
// "var_end" is the end of the variable/option/etc. name.
lhs->lhs_dest_end = skip_var_one(var_start, FALSE);
if (*var_start == '@')
+ {
+ if (!valid_dest_reg(var_start[1]))
+ return FAIL;
var_end = var_start + 2;
+ }
else
{
// skip over the leading "&", "&l:", "&g:" and "$"
*** ../vim-9.0.0741/src/vim9cmds.c 2022-10-11 21:41:21.446173722 +0100
--- src/vim9cmds.c 2022-10-13 15:53:05.036099874 +0100
***************
*** 2412,2445 ****
{
if (STRNCMP(arg, "END", 3) == 0)
{
! if (lhs->lhs_append)
{
! // First load the current variable value.
! if (compile_load_lhs_with_index(lhs, lhs->lhs_whole,
cctx) == FAIL)
! return NULL;
! }
!
! // Gets the redirected text and put it on the stack, then store it
! // in the variable.
! generate_instr_type(cctx, ISN_REDIREND, &t_string);
!
! if (lhs->lhs_append)
! generate_CONCAT(cctx, 2);

! if (lhs->lhs_has_index)
! {
! // Use the info in "lhs" to store the value at the index in the
! // list or dict.
! if (compile_assign_unlet(lhs->lhs_whole, lhs, TRUE,
&t_string, cctx) == FAIL)
return NULL;
- }
- else if (generate_store_lhs(cctx, lhs, -1, FALSE) == FAIL)
- return NULL;

! VIM_CLEAR(lhs->lhs_name);
! VIM_CLEAR(lhs->lhs_whole);
return arg + 3;
}
emsg(_(e_cannot_nest_redir));
--- 2412,2448 ----
{
if (STRNCMP(arg, "END", 3) == 0)
{
! if (cctx->ctx_skip != SKIP_YES)
{
! if (lhs->lhs_append)
! {
! // First load the current variable value.
! if (compile_load_lhs_with_index(lhs, lhs->lhs_whole,
cctx) == FAIL)
! return NULL;
! }

! // Gets the redirected text and put it on the stack, then store
! // it in the variable.
! generate_instr_type(cctx, ISN_REDIREND, &t_string);
!
! if (lhs->lhs_append)
! generate_CONCAT(cctx, 2);
!
! if (lhs->lhs_has_index)
! {
! // Use the info in "lhs" to store the value at the index in
! // the list or dict.
! if (compile_assign_unlet(lhs->lhs_whole, lhs, TRUE,
&t_string, cctx) == FAIL)
+ return NULL;
+ }
+ else if (generate_store_lhs(cctx, lhs, -1, FALSE) == FAIL)
return NULL;

! VIM_CLEAR(lhs->lhs_name);
! VIM_CLEAR(lhs->lhs_whole);
! }
return arg + 3;
}
emsg(_(e_cannot_nest_redir));
***************
*** 2465,2477 ****
if (need_type(&t_string, lhs->lhs_member_type,
-1, 0, cctx, FALSE, FALSE) == FAIL)
return NULL;
! generate_instr(cctx, ISN_REDIRSTART);
! lhs->lhs_append = append;
! if (lhs->lhs_has_index)
{
! lhs->lhs_whole = vim_strnsave(arg, lhs->lhs_varlen_total);
! if (lhs->lhs_whole == NULL)
! return NULL;
}

return arg + lhs->lhs_varlen_total;
--- 2468,2487 ----
if (need_type(&t_string, lhs->lhs_member_type,
-1, 0, cctx, FALSE, FALSE) == FAIL)
return NULL;
! if (cctx->ctx_skip == SKIP_YES)
! {
! VIM_CLEAR(lhs->lhs_name);
! }
! else
{
! generate_instr(cctx, ISN_REDIRSTART);
! lhs->lhs_append = append;
! if (lhs->lhs_has_index)
! {
! lhs->lhs_whole = vim_strnsave(arg, lhs->lhs_varlen_total);
! if (lhs->lhs_whole == NULL)
! return NULL;
! }
}

return arg + lhs->lhs_varlen_total;
*** ../vim-9.0.0741/src/testdir/test_vim9_func.vim 2022-09-30 19:19:00.769677730 +0100
--- src/testdir/test_vim9_func.vim 2022-10-13 15:39:22.488958480 +0100
***************
*** 4339,4344 ****
--- 4339,4371 ----
assert_equal('', glob('XdeferFile'))
enddef

+ def Test_invalid_redir()
+ var lines =<< trim END
+ def Tone()
+ if 1
+ redi =>@ \\\
\\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
Reply all
Reply to author
Forward
0 new messages