Projects
Mega:23.09
vim
_service:tar_scm:backport-CVE-2022-3491.patch
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File _service:tar_scm:backport-CVE-2022-3491.patch of Package vim
From 3558afe9e9e904cabb8475392d859f2d2fc21041 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar <Bram@vim.org> Date: Thu, 13 Oct 2022 16:12:57 +0100 Subject: [PATCH] patch 9.0.0742: reading past end of the line when compiling a function Problem: Reading past end of the line when compiling a function with errors. Solution: Do not return an invalid pointer. Fix skipping redirection. --- src/testdir/test_vim9_func.vim | 27 ++++++++++++++ src/testdir/test_vim9_script.vim | 55 ++++++++++++++++++++++++++-- src/vim9cmds.c | 62 ++++++++++++++++++-------------- src/vim9compile.c | 23 +++++++++--- 4 files changed, 134 insertions(+), 33 deletions(-) diff --git a/src/testdir/test_vim9_func.vim b/src/testdir/test_vim9_func.vim index 38766e330156..bb5635626484 100644 --- a/src/testdir/test_vim9_func.vim +++ b/src/testdir/test_vim9_func.vim @@ -4217,6 +4217,33 @@ def Test_multiple_funcref() v9.CheckScriptSuccess(lines) enddef +def Test_invalid_redir() + var lines =<< trim END + def Tone() + if 1 + redi =>@0 + redi END + endif + enddef + defcompile + END + v9.CheckScriptFailure(lines, 'E354:') + delfunc g:Tone + + # this was reading past the end of the line + lines =<< trim END + def Ttwo() + if 0 + redi =>@0 + redi END + endif + enddef + defcompile + END + v9.CheckScriptFailure(lines, 'E354:') + delfunc g:Ttwo +enddef + " The following messes up syntax highlight, keep near the end. if has('python3') def Test_python3_command() diff --git a/src/testdir/test_vim9_script.vim b/src/testdir/test_vim9_script.vim index a0b8352f3f72..6c8f1f0ce0b0 100644 --- a/src/testdir/test_vim9_script.vim +++ b/src/testdir/test_vim9_script.vim @@ -2112,15 +2112,66 @@ enddef def Test_skipped_redir() var lines =<< trim END - def T() + def Tredir() if 0 - redir =>l[0] + redir => l[0] redir END endif enddef defcompile END v9.CheckScriptSuccess(lines) + delfunc g:Tredir + + lines =<< trim END + def Tredir() + if 0 + redir => l[0] + endif + echo 'executed' + if 0 + redir END + endif + enddef + defcompile + END + v9.CheckScriptSuccess(lines) + delfunc g:Tredir + + lines =<< trim END + def Tredir() + var l = [''] + if 1 + redir => l[0] + endif + echo 'executed' + if 0 + redir END + else + redir END + endif + enddef + defcompile + END + v9.CheckScriptSuccess(lines) + delfunc g:Tredir + + lines =<< trim END + let doit = 1 + def Tredir() + var l = [''] + if g:doit + redir => l[0] + endif + echo 'executed' + if g:doit + redir END + endif + enddef + defcompile + END + v9.CheckScriptSuccess(lines) + delfunc g:Tredir enddef def Test_for_loop() diff --git a/src/vim9cmds.c b/src/vim9cmds.c index 73f95b26dfe5..e5abf895e6a7 100644 --- a/src/vim9cmds.c +++ b/src/vim9cmds.c @@ -2123,34 +2123,37 @@ compile_redir(char_u *line, exarg_T *eap, cctx_T *cctx) { if (STRNCMP(arg, "END", 3) == 0) { - if (lhs->lhs_append) + if (cctx->ctx_skip != SKIP_YES) { - // First load the current variable value. - if (compile_load_lhs_with_index(lhs, lhs->lhs_whole, + if (lhs->lhs_append) + { + // First load the current variable value. + if (compile_load_lhs_with_index(lhs, lhs->lhs_whole, cctx) == FAIL) - return NULL; - } + 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); + // 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_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, + 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; - } - else if (generate_store_lhs(cctx, lhs, -1, FALSE) == FAIL) - return NULL; - VIM_CLEAR(lhs->lhs_name); - VIM_CLEAR(lhs->lhs_whole); + VIM_CLEAR(lhs->lhs_name); + VIM_CLEAR(lhs->lhs_whole); + } return arg + 3; } emsg(_(e_cannot_nest_redir)); @@ -2176,13 +2179,20 @@ compile_redir(char_u *line, exarg_T *eap, cctx_T *cctx) 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) + if (cctx->ctx_skip == SKIP_YES) { - lhs->lhs_whole = vim_strnsave(arg, lhs->lhs_varlen_total); - if (lhs->lhs_whole == NULL) - return NULL; + 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; diff --git a/src/vim9compile.c b/src/vim9compile.c index b3e1b83ea4ef..73bfa6c6af1e 100644 --- a/src/vim9compile.c +++ b/src/vim9compile.c @@ -1217,6 +1217,19 @@ vim9_declare_error(char_u *name) semsg(_(e_cannot_declare_a_scope_variable), scope, name); } +/* + * 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. @@ -1298,12 +1311,8 @@ get_var_dest( } else if (*name == '@') { - if (name[1] != '@' - && (!valid_yank_reg(name[1], FALSE) || name[1] == '.')) - { - emsg_invreg(name[1]); + if (!valid_dest_reg(name[1])) return FAIL; - } *dest = dest_reg; *type = name[1] == '#' ? &t_number_or_string : &t_string; } @@ -1379,7 +1388,11 @@ compile_lhs( // "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 "$"
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.
浙ICP备2022010568号-2