fix CVE-2022-1785
(cherry picked from commit 9d353b5e3a381197f33382a10a55111ac2b7db95)
This commit is contained in:
parent
264ff3d4a5
commit
3225c60546
76
backport-CVE-2022-1785.patch
Normal file
76
backport-CVE-2022-1785.patch
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
From e2bd8600b873d2cd1f9d667c28cba8b1dba18839 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Bram Moolenaar <Bram@vim.org>
|
||||||
|
Date: Wed, 18 May 2022 13:11:57 +0100
|
||||||
|
Subject: [PATCH] patch 8.2.4977: memory access error when substitute
|
||||||
|
expression changes window
|
||||||
|
|
||||||
|
Problem: Memory access error when substitute expression changes window.
|
||||||
|
Solution: Disallow changing window in substitute expression.
|
||||||
|
---
|
||||||
|
src/ex_cmds.c | 11 +++++++++++
|
||||||
|
src/testdir/test_substitute.vim | 14 ++++++++++++++
|
||||||
|
2 files changed, 25 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/src/ex_cmds.c b/src/ex_cmds.c
|
||||||
|
index aa97b40..0a22f59 100644
|
||||||
|
--- a/src/ex_cmds.c
|
||||||
|
+++ b/src/ex_cmds.c
|
||||||
|
@@ -4289,12 +4289,17 @@ do_sub(exarg_T *eap)
|
||||||
|
// Save flags for recursion. They can change for e.g.
|
||||||
|
// :s/^/\=execute("s#^##gn")
|
||||||
|
subflags_save = subflags;
|
||||||
|
+
|
||||||
|
+ // Disallow changing text or switching window in an expression.
|
||||||
|
+ ++textwinlock;
|
||||||
|
#endif
|
||||||
|
// get length of substitution part
|
||||||
|
sublen = vim_regsub_multi(®match,
|
||||||
|
sub_firstlnum - regmatch.startpos[0].lnum,
|
||||||
|
sub, sub_firstline, FALSE, p_magic, TRUE);
|
||||||
|
#ifdef FEAT_EVAL
|
||||||
|
+ --textwinlock;
|
||||||
|
+
|
||||||
|
// If getting the substitute string caused an error, don't do
|
||||||
|
// the replacement.
|
||||||
|
// Don't keep flags set by a recursive call.
|
||||||
|
@@ -4395,9 +4400,15 @@ do_sub(exarg_T *eap)
|
||||||
|
mch_memmove(new_end, sub_firstline + copycol, (size_t)copy_len);
|
||||||
|
new_end += copy_len;
|
||||||
|
|
||||||
|
+#ifdef FEAT_EVAL
|
||||||
|
+ ++textwinlock;
|
||||||
|
+#endif
|
||||||
|
(void)vim_regsub_multi(®match,
|
||||||
|
sub_firstlnum - regmatch.startpos[0].lnum,
|
||||||
|
sub, new_end, TRUE, p_magic, TRUE);
|
||||||
|
+#ifdef FEAT_EVAL
|
||||||
|
+ --textwinlock;
|
||||||
|
+#endif
|
||||||
|
sub_nsubs++;
|
||||||
|
did_sub = TRUE;
|
||||||
|
|
||||||
|
diff --git a/src/testdir/test_substitute.vim b/src/testdir/test_substitute.vim
|
||||||
|
index 3e6bc5c..bda96f6 100644
|
||||||
|
--- a/src/testdir/test_substitute.vim
|
||||||
|
+++ b/src/testdir/test_substitute.vim
|
||||||
|
@@ -761,3 +761,17 @@ func Test_using_old_sub()
|
||||||
|
bwipe!
|
||||||
|
set nocompatible
|
||||||
|
endfunc
|
||||||
|
+
|
||||||
|
+" This was switching windows in between computing the length and using it.
|
||||||
|
+func Test_sub_change_window()
|
||||||
|
+ silent! lfile
|
||||||
|
+ sil! norm o0000000000000000000000000000000000000000000000000000
|
||||||
|
+ func Repl()
|
||||||
|
+ lopen
|
||||||
|
+ endfunc
|
||||||
|
+ silent! s/\%')/\=Repl()
|
||||||
|
+ bwipe!
|
||||||
|
+ bwipe!
|
||||||
|
+ delfunc Repl
|
||||||
|
+endfunc
|
||||||
|
+
|
||||||
|
--
|
||||||
|
1.8.3.1
|
||||||
|
|
||||||
@ -0,0 +1,242 @@
|
|||||||
|
From ff06f283e3e4b3ec43012dd3b83f8454c98f6639 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Bram Moolenaar <Bram@vim.org>
|
||||||
|
Date: Tue, 21 Apr 2020 22:01:14 +0200
|
||||||
|
Subject: [PATCH] patch 8.2.0614: get ml_get error when deleting a line in
|
||||||
|
'completefunc'
|
||||||
|
|
||||||
|
Problem: Get ml_get error when deleting a line in 'completefunc'. (Yegappan
|
||||||
|
Lakshmanan)
|
||||||
|
Solution: Lock the text while evaluating 'completefunc'.
|
||||||
|
---
|
||||||
|
runtime/doc/insert.txt | 6 ++++--
|
||||||
|
src/edit.c | 10 ++--------
|
||||||
|
src/ex_getln.c | 2 +-
|
||||||
|
src/globals.h | 5 +++--
|
||||||
|
src/insexpand.c | 22 ++++++++++++++--------
|
||||||
|
src/testdir/test_edit.vim | 21 +++++++++++++++++++--
|
||||||
|
src/testdir/test_popup.vim | 10 ++++------
|
||||||
|
src/undo.c | 2 +-
|
||||||
|
8 files changed, 48 insertions(+), 30 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/runtime/doc/insert.txt b/runtime/doc/insert.txt
|
||||||
|
index 99c2d40..ff74d62 100644
|
||||||
|
--- a/runtime/doc/insert.txt
|
||||||
|
+++ b/runtime/doc/insert.txt
|
||||||
|
@@ -666,8 +666,10 @@ Note: The keys that are valid in CTRL-X mode are not mapped. This allows for
|
||||||
|
ends CTRL-X mode (any key that is not a valid CTRL-X mode command) is mapped.
|
||||||
|
Also, when doing completion with 'complete' mappings apply as usual.
|
||||||
|
|
||||||
|
-Note: While completion is active Insert mode can't be used recursively.
|
||||||
|
-Mappings that somehow invoke ":normal i.." will generate an E523 error.
|
||||||
|
+ *E565*
|
||||||
|
+Note: While completion is active Insert mode can't be used recursively and
|
||||||
|
+buffer text cannot be changed. Mappings that somehow invoke ":normal i.."
|
||||||
|
+will generate an E565 error.
|
||||||
|
|
||||||
|
The following mappings are suggested to make typing the completion commands
|
||||||
|
a bit easier (although they will hide other commands): >
|
||||||
|
diff --git a/src/edit.c b/src/edit.c
|
||||||
|
index 3f0803f..05518ce 100644
|
||||||
|
--- a/src/edit.c
|
||||||
|
+++ b/src/edit.c
|
||||||
|
@@ -175,16 +175,10 @@ edit(
|
||||||
|
#endif
|
||||||
|
// Don't allow changes in the buffer while editing the cmdline. The
|
||||||
|
// caller of getcmdline() may get confused.
|
||||||
|
- if (textlock != 0)
|
||||||
|
- {
|
||||||
|
- emsg(_(e_secure));
|
||||||
|
- return FALSE;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
// Don't allow recursive insert mode when busy with completion.
|
||||||
|
- if (ins_compl_active() || compl_busy || pum_visible())
|
||||||
|
+ if (textlock != 0 || ins_compl_active() || compl_busy || pum_visible())
|
||||||
|
{
|
||||||
|
- emsg(_(e_secure));
|
||||||
|
+ emsg(_(e_textlock));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
ins_compl_clear(); // clear stuff for CTRL-X mode
|
||||||
|
diff --git a/src/ex_getln.c b/src/ex_getln.c
|
||||||
|
index 9b959fb..18da926 100644
|
||||||
|
--- a/src/ex_getln.c
|
||||||
|
+++ b/src/ex_getln.c
|
||||||
|
@@ -2576,7 +2576,7 @@ get_text_locked_msg(void)
|
||||||
|
if (cmdwin_type != 0)
|
||||||
|
return e_cmdwin;
|
||||||
|
#endif
|
||||||
|
- return e_secure;
|
||||||
|
+ return e_textlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
diff --git a/src/globals.h b/src/globals.h
|
||||||
|
index 4822bf3..f6c9d60 100644
|
||||||
|
--- a/src/globals.h
|
||||||
|
+++ b/src/globals.h
|
||||||
|
@@ -1678,9 +1678,10 @@ EXTERN char e_letunexp[] INIT(= N_("E18: Unexpected characters in :let"));
|
||||||
|
EXTERN char e_readerrf[] INIT(= N_("E47: Error while reading errorfile"));
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_SANDBOX
|
||||||
|
-EXTERN char e_sandbox[] INIT(= N_("E48: Not allowed in sandbox"));
|
||||||
|
+EXTERN char e_sandbox[] INIT(= N_("E48: Not allowed in sandbox"));
|
||||||
|
#endif
|
||||||
|
-EXTERN char e_secure[] INIT(= N_("E523: Not allowed here"));
|
||||||
|
+EXTERN char e_secure[] INIT(= N_("E523: Not allowed here"));
|
||||||
|
+EXTERN char e_textlock[] INIT(= N_("E565: Not allowed to change text here"));
|
||||||
|
#if defined(AMIGA) || defined(MACOS_X) || defined(MSWIN) \
|
||||||
|
|| defined(UNIX) || defined(VMS)
|
||||||
|
EXTERN char e_screenmode[] INIT(= N_("E359: Screen mode setting not supported"));
|
||||||
|
diff --git a/src/insexpand.c b/src/insexpand.c
|
||||||
|
index 0278522..48ab260 100644
|
||||||
|
--- a/src/insexpand.c
|
||||||
|
+++ b/src/insexpand.c
|
||||||
|
@@ -2217,6 +2217,8 @@ expand_by_function(
|
||||||
|
pos = curwin->w_cursor;
|
||||||
|
curwin_save = curwin;
|
||||||
|
curbuf_save = curbuf;
|
||||||
|
+ // Lock the text to avoid weird things from happening.
|
||||||
|
+ ++textlock;
|
||||||
|
|
||||||
|
// Call a function, which returns a list or dict.
|
||||||
|
if (call_vim_function(funcname, 2, args, &rettv) == OK)
|
||||||
|
@@ -2239,6 +2241,7 @@ expand_by_function(
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+ --textlock;
|
||||||
|
|
||||||
|
if (curwin_save != curwin || curbuf_save != curbuf)
|
||||||
|
{
|
||||||
|
@@ -2431,6 +2434,7 @@ set_completion(colnr_T startcol, list_T *list)
|
||||||
|
f_complete(typval_T *argvars, typval_T *rettv UNUSED)
|
||||||
|
{
|
||||||
|
int startcol;
|
||||||
|
+ int save_textlock = textlock;
|
||||||
|
|
||||||
|
if ((State & INSERT) == 0)
|
||||||
|
{
|
||||||
|
@@ -2438,22 +2442,24 @@ f_complete(typval_T *argvars, typval_T *rettv UNUSED)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ // "textlock" is set when evaluating 'completefunc' but we can change text
|
||||||
|
+ // here.
|
||||||
|
+ textlock = 0;
|
||||||
|
+
|
||||||
|
// Check for undo allowed here, because if something was already inserted
|
||||||
|
// the line was already saved for undo and this check isn't done.
|
||||||
|
if (!undo_allowed())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (argvars[1].v_type != VAR_LIST || argvars[1].vval.v_list == NULL)
|
||||||
|
- {
|
||||||
|
emsg(_(e_invarg));
|
||||||
|
- return;
|
||||||
|
+ else
|
||||||
|
+ {
|
||||||
|
+ startcol = (int)tv_get_number_chk(&argvars[0], NULL);
|
||||||
|
+ if (startcol > 0)
|
||||||
|
+ set_completion(startcol - 1, argvars[1].vval.v_list);
|
||||||
|
}
|
||||||
|
-
|
||||||
|
- startcol = (int)tv_get_number_chk(&argvars[0], NULL);
|
||||||
|
- if (startcol <= 0)
|
||||||
|
- return;
|
||||||
|
-
|
||||||
|
- set_completion(startcol - 1, argvars[1].vval.v_list);
|
||||||
|
+ textlock = save_textlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
diff --git a/src/testdir/test_edit.vim b/src/testdir/test_edit.vim
|
||||||
|
index 9096fcd..ce55f6b 100644
|
||||||
|
--- a/src/testdir/test_edit.vim
|
||||||
|
+++ b/src/testdir/test_edit.vim
|
||||||
|
@@ -915,6 +915,23 @@ func Test_edit_CTRL_U()
|
||||||
|
bw!
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
+func Test_edit_completefunc_delete()
|
||||||
|
+ func CompleteFunc(findstart, base)
|
||||||
|
+ if a:findstart == 1
|
||||||
|
+ return col('.') - 1
|
||||||
|
+ endif
|
||||||
|
+ normal dd
|
||||||
|
+ return ['a', 'b']
|
||||||
|
+ endfunc
|
||||||
|
+ new
|
||||||
|
+ set completefunc=CompleteFunc
|
||||||
|
+ call setline(1, ['', 'abcd', ''])
|
||||||
|
+ 2d
|
||||||
|
+ call assert_fails("normal 2G$a\<C-X>\<C-U>", 'E565:')
|
||||||
|
+ bwipe!
|
||||||
|
+endfunc
|
||||||
|
+
|
||||||
|
+
|
||||||
|
func Test_edit_CTRL_Z()
|
||||||
|
" Ctrl-Z when insertmode is not set inserts it literally
|
||||||
|
new
|
||||||
|
@@ -1240,7 +1257,7 @@ func Test_edit_forbidden()
|
||||||
|
try
|
||||||
|
call feedkeys("ix\<esc>", 'tnix')
|
||||||
|
call assert_fails(1, 'textlock')
|
||||||
|
- catch /^Vim\%((\a\+)\)\=:E523/ " catch E523: not allowed here
|
||||||
|
+ catch /^Vim\%((\a\+)\)\=:E565/ " catch E565: not allowed here
|
||||||
|
endtry
|
||||||
|
" TODO: Might be a bug: should x really be inserted here
|
||||||
|
call assert_equal(['xa'], getline(1, '$'))
|
||||||
|
@@ -1264,7 +1281,7 @@ func Test_edit_forbidden()
|
||||||
|
try
|
||||||
|
call feedkeys("i\<c-x>\<c-u>\<esc>", 'tnix')
|
||||||
|
call assert_fails(1, 'change in complete function')
|
||||||
|
- catch /^Vim\%((\a\+)\)\=:E523/ " catch E523
|
||||||
|
+ catch /^Vim\%((\a\+)\)\=:E565/ " catch E565
|
||||||
|
endtry
|
||||||
|
delfu Complete
|
||||||
|
set completefunc=
|
||||||
|
diff --git a/src/testdir/test_popup.vim b/src/testdir/test_popup.vim
|
||||||
|
index e96d5fd..9890377 100644
|
||||||
|
--- a/src/testdir/test_popup.vim
|
||||||
|
+++ b/src/testdir/test_popup.vim
|
||||||
|
@@ -334,19 +334,17 @@ func DummyCompleteOne(findstart, base)
|
||||||
|
endif
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
-" Test that nothing happens if the 'completefunc' opens
|
||||||
|
-" a new window (no completion, no crash)
|
||||||
|
+" Test that nothing happens if the 'completefunc' tries to open
|
||||||
|
+" a new window (fails to open window, continues)
|
||||||
|
func Test_completefunc_opens_new_window_one()
|
||||||
|
new
|
||||||
|
let winid = win_getid()
|
||||||
|
setlocal completefunc=DummyCompleteOne
|
||||||
|
call setline(1, 'one')
|
||||||
|
/^one
|
||||||
|
- call assert_fails('call feedkeys("A\<C-X>\<C-U>\<C-N>\<Esc>", "x")', 'E839:')
|
||||||
|
- call assert_notequal(winid, win_getid())
|
||||||
|
- q!
|
||||||
|
+ call assert_fails('call feedkeys("A\<C-X>\<C-U>\<C-N>\<Esc>", "x")', 'E565:')
|
||||||
|
call assert_equal(winid, win_getid())
|
||||||
|
- call assert_equal('', getline(1))
|
||||||
|
+ call assert_equal('oneDEF', getline(1))
|
||||||
|
q!
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
diff --git a/src/undo.c b/src/undo.c
|
||||||
|
index c5ce306..c11b048 100644
|
||||||
|
--- a/src/undo.c
|
||||||
|
+++ b/src/undo.c
|
||||||
|
@@ -333,7 +333,7 @@ undo_allowed(void)
|
||||||
|
// caller of getcmdline() may get confused.
|
||||||
|
if (textlock != 0)
|
||||||
|
{
|
||||||
|
- emsg(_(e_secure));
|
||||||
|
+ emsg(_(e_textlock));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
1.8.3.1
|
||||||
|
|
||||||
@ -0,0 +1,443 @@
|
|||||||
|
From 6adb9ea0a6ca01414f4b591f379b0f829a8273c0 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Bram Moolenaar <Bram@vim.org>
|
||||||
|
Date: Thu, 30 Apr 2020 22:31:18 +0200
|
||||||
|
Subject: [PATCH] patch 8.2.0670: cannot change window when evaluating
|
||||||
|
'completefunc'
|
||||||
|
|
||||||
|
Problem: Cannot change window when evaluating 'completefunc'.
|
||||||
|
Solution: Make a difference between not changing text or buffers and also
|
||||||
|
not changing window.
|
||||||
|
---
|
||||||
|
src/beval.c | 4 ++--
|
||||||
|
src/change.c | 4 ++--
|
||||||
|
src/edit.c | 9 +++++----
|
||||||
|
src/eval.c | 10 +++++-----
|
||||||
|
src/ex_docmd.c | 2 +-
|
||||||
|
src/ex_getln.c | 30 +++++++++++++++++++++---------
|
||||||
|
src/globals.h | 13 ++++++++++---
|
||||||
|
src/indent.c | 4 ++--
|
||||||
|
src/insexpand.c | 11 ++++++-----
|
||||||
|
src/map.c | 4 ++--
|
||||||
|
src/proto/ex_getln.pro | 3 ++-
|
||||||
|
src/register.c | 4 ++--
|
||||||
|
src/testdir/test_edit.vim | 2 +-
|
||||||
|
src/testdir/test_popup.vim | 2 +-
|
||||||
|
src/undo.c | 2 +-
|
||||||
|
src/window.c | 2 +-
|
||||||
|
16 files changed, 64 insertions(+), 42 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/beval.c b/src/beval.c
|
||||||
|
index 6b10a65..b7d9226 100644
|
||||||
|
--- a/src/beval.c
|
||||||
|
+++ b/src/beval.c
|
||||||
|
@@ -282,7 +282,7 @@ general_beval_cb(BalloonEval *beval, int state UNUSED)
|
||||||
|
curbuf = save_curbuf;
|
||||||
|
if (use_sandbox)
|
||||||
|
++sandbox;
|
||||||
|
- ++textlock;
|
||||||
|
+ ++textwinlock;
|
||||||
|
|
||||||
|
vim_free(result);
|
||||||
|
result = eval_to_string(bexpr, NULL, TRUE);
|
||||||
|
@@ -299,7 +299,7 @@ general_beval_cb(BalloonEval *beval, int state UNUSED)
|
||||||
|
|
||||||
|
if (use_sandbox)
|
||||||
|
--sandbox;
|
||||||
|
- --textlock;
|
||||||
|
+ --textwinlock;
|
||||||
|
|
||||||
|
set_vim_var_string(VV_BEVAL_TEXT, NULL, -1);
|
||||||
|
if (result != NULL && result[0] != NUL)
|
||||||
|
diff --git a/src/change.c b/src/change.c
|
||||||
|
index cfba90b..45d6704 100644
|
||||||
|
--- a/src/change.c
|
||||||
|
+++ b/src/change.c
|
||||||
|
@@ -382,7 +382,7 @@ invoke_listeners(buf_T *buf)
|
||||||
|
|
||||||
|
argv[4].v_type = VAR_LIST;
|
||||||
|
argv[4].vval.v_list = buf->b_recorded_changes;
|
||||||
|
- ++textlock;
|
||||||
|
+ ++textwinlock;
|
||||||
|
|
||||||
|
for (lnr = buf->b_listener; lnr != NULL; lnr = lnr->lr_next)
|
||||||
|
{
|
||||||
|
@@ -390,7 +390,7 @@ invoke_listeners(buf_T *buf)
|
||||||
|
clear_tv(&rettv);
|
||||||
|
}
|
||||||
|
|
||||||
|
- --textlock;
|
||||||
|
+ --textwinlock;
|
||||||
|
list_unref(buf->b_recorded_changes);
|
||||||
|
buf->b_recorded_changes = NULL;
|
||||||
|
|
||||||
|
diff --git a/src/edit.c b/src/edit.c
|
||||||
|
index 7f4f765..0ac63ec 100644
|
||||||
|
--- a/src/edit.c
|
||||||
|
+++ b/src/edit.c
|
||||||
|
@@ -176,9 +176,10 @@ edit(
|
||||||
|
// Don't allow changes in the buffer while editing the cmdline. The
|
||||||
|
// caller of getcmdline() may get confused.
|
||||||
|
// Don't allow recursive insert mode when busy with completion.
|
||||||
|
- if (textlock != 0 || ins_compl_active() || compl_busy || pum_visible())
|
||||||
|
+ if (textwinlock != 0 || textlock != 0
|
||||||
|
+ || ins_compl_active() || compl_busy || pum_visible())
|
||||||
|
{
|
||||||
|
- emsg(_(e_textlock));
|
||||||
|
+ emsg(_(e_textwinlock));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
ins_compl_clear(); // clear stuff for CTRL-X mode
|
||||||
|
@@ -5944,7 +5945,7 @@ do_insert_char_pre(int c)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lock the text to avoid weird things from happening.
|
||||||
|
- ++textlock;
|
||||||
|
+ ++textwinlock;
|
||||||
|
set_vim_var_string(VV_CHAR, buf, -1); // set v:char
|
||||||
|
|
||||||
|
res = NULL;
|
||||||
|
@@ -5958,7 +5959,7 @@ do_insert_char_pre(int c)
|
||||||
|
}
|
||||||
|
|
||||||
|
set_vim_var_string(VV_CHAR, NULL, -1); // clear v:char
|
||||||
|
- --textlock;
|
||||||
|
+ --textwinlock;
|
||||||
|
|
||||||
|
// Restore the State, it may have been changed.
|
||||||
|
State = save_State;
|
||||||
|
diff --git a/src/eval.c b/src/eval.c
|
||||||
|
index 4bd45e9..31dde2f 100644
|
||||||
|
--- a/src/eval.c
|
||||||
|
+++ b/src/eval.c
|
||||||
|
@@ -393,7 +393,7 @@ eval_to_string(
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Call eval_to_string() without using current local variables and using
|
||||||
|
- * textlock. When "use_sandbox" is TRUE use the sandbox.
|
||||||
|
+ * textwinlock. When "use_sandbox" is TRUE use the sandbox.
|
||||||
|
*/
|
||||||
|
char_u *
|
||||||
|
eval_to_string_safe(
|
||||||
|
@@ -407,11 +407,11 @@ eval_to_string_safe(
|
||||||
|
save_funccal(&funccal_entry);
|
||||||
|
if (use_sandbox)
|
||||||
|
++sandbox;
|
||||||
|
- ++textlock;
|
||||||
|
+ ++textwinlock;
|
||||||
|
retval = eval_to_string(arg, nextcmd, FALSE);
|
||||||
|
if (use_sandbox)
|
||||||
|
--sandbox;
|
||||||
|
- --textlock;
|
||||||
|
+ --textwinlock;
|
||||||
|
restore_funccal();
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
@@ -576,7 +576,7 @@ eval_foldexpr(char_u *arg, int *cp)
|
||||||
|
++emsg_off;
|
||||||
|
if (use_sandbox)
|
||||||
|
++sandbox;
|
||||||
|
- ++textlock;
|
||||||
|
+ ++textwinlock;
|
||||||
|
*cp = NUL;
|
||||||
|
if (eval0(arg, &tv, NULL, TRUE) == FAIL)
|
||||||
|
retval = 0;
|
||||||
|
@@ -601,7 +601,7 @@ eval_foldexpr(char_u *arg, int *cp)
|
||||||
|
--emsg_off;
|
||||||
|
if (use_sandbox)
|
||||||
|
--sandbox;
|
||||||
|
- --textlock;
|
||||||
|
+ --textwinlock;
|
||||||
|
|
||||||
|
return (int)retval;
|
||||||
|
}
|
||||||
|
diff --git a/src/ex_docmd.c b/src/ex_docmd.c
|
||||||
|
index ca69c29..65ef936 100644
|
||||||
|
--- a/src/ex_docmd.c
|
||||||
|
+++ b/src/ex_docmd.c
|
||||||
|
@@ -5749,7 +5749,7 @@ handle_drop(
|
||||||
|
handle_any_postponed_drop(void)
|
||||||
|
{
|
||||||
|
if (!drop_busy && drop_filev != NULL
|
||||||
|
- && !text_locked() && !curbuf_locked() && !updating_screen)
|
||||||
|
+ && !text_locked() && !curbuf_locked() && !updating_screen)
|
||||||
|
handle_drop_internal();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
diff --git a/src/ex_getln.c b/src/ex_getln.c
|
||||||
|
index 6376a5f..48d40cf 100644
|
||||||
|
--- a/src/ex_getln.c
|
||||||
|
+++ b/src/ex_getln.c
|
||||||
|
@@ -1318,12 +1318,12 @@ getcmdline_int(
|
||||||
|
c = get_expr_register();
|
||||||
|
if (c == '=')
|
||||||
|
{
|
||||||
|
- // Need to save and restore ccline. And set "textlock"
|
||||||
|
+ // Need to save and restore ccline. And set "textwinlock"
|
||||||
|
// to avoid nasty things like going to another buffer when
|
||||||
|
// evaluating an expression.
|
||||||
|
- ++textlock;
|
||||||
|
+ ++textwinlock;
|
||||||
|
p = get_expr_line();
|
||||||
|
- --textlock;
|
||||||
|
+ --textwinlock;
|
||||||
|
|
||||||
|
if (p != NULL)
|
||||||
|
{
|
||||||
|
@@ -2548,17 +2548,17 @@ check_opt_wim(void)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return TRUE when the text must not be changed and we can't switch to
|
||||||
|
- * another window or buffer. Used when editing the command line, evaluating
|
||||||
|
+ * another window or buffer. TRUE when editing the command line, evaluating
|
||||||
|
* 'balloonexpr', etc.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
-text_locked(void)
|
||||||
|
+text_and_win_locked(void)
|
||||||
|
{
|
||||||
|
#ifdef FEAT_CMDWIN
|
||||||
|
if (cmdwin_type != 0)
|
||||||
|
return TRUE;
|
||||||
|
#endif
|
||||||
|
- return textlock != 0;
|
||||||
|
+ return textwinlock != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
@@ -2578,10 +2578,22 @@ get_text_locked_msg(void)
|
||||||
|
if (cmdwin_type != 0)
|
||||||
|
return e_cmdwin;
|
||||||
|
#endif
|
||||||
|
+ if (textwinlock != 0)
|
||||||
|
+ return e_textwinlock;
|
||||||
|
return e_textlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
+ * Return TRUE when the text must not be changed and/or we cannot switch to
|
||||||
|
+ * another window. TRUE while evaluating 'completefunc'.
|
||||||
|
+ */
|
||||||
|
+ int
|
||||||
|
+text_locked(void)
|
||||||
|
+{
|
||||||
|
+ return text_and_win_locked() || textlock != 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
* Check if "curbuf_lock" or "allbuf_lock" is set and return TRUE when it is
|
||||||
|
* and give an error message.
|
||||||
|
*/
|
||||||
|
@@ -3560,11 +3572,11 @@ cmdline_paste(
|
||||||
|
regname = may_get_selection(regname);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
- // Need to set "textlock" to avoid nasty things like going to another
|
||||||
|
+ // Need to set "textwinlock" to avoid nasty things like going to another
|
||||||
|
// buffer when evaluating an expression.
|
||||||
|
- ++textlock;
|
||||||
|
+ ++textwinlock;
|
||||||
|
i = get_spec_reg(regname, &arg, &allocated, TRUE);
|
||||||
|
- --textlock;
|
||||||
|
+ --textwinlock;
|
||||||
|
|
||||||
|
if (i)
|
||||||
|
{
|
||||||
|
diff --git a/src/globals.h b/src/globals.h
|
||||||
|
index 2dceab5..9180bef 100644
|
||||||
|
--- a/src/globals.h
|
||||||
|
+++ b/src/globals.h
|
||||||
|
@@ -798,9 +798,15 @@ EXTERN int secure INIT(= FALSE);
|
||||||
|
// allowed, e.g. when sourcing .exrc or .vimrc
|
||||||
|
// in current directory
|
||||||
|
|
||||||
|
-EXTERN int textlock INIT(= 0);
|
||||||
|
+EXTERN int textwinlock INIT(= 0);
|
||||||
|
// non-zero when changing text and jumping to
|
||||||
|
- // another window or buffer is not allowed
|
||||||
|
+ // another window or editing another buffer is
|
||||||
|
+ // not allowed
|
||||||
|
+
|
||||||
|
+EXTERN int textlock INIT(= 0);
|
||||||
|
+ // non-zero when changing text is not allowed,
|
||||||
|
+ // jumping to another window is allowed,
|
||||||
|
+ // editing another buffer is not allowed.
|
||||||
|
|
||||||
|
EXTERN int curbuf_lock INIT(= 0);
|
||||||
|
// non-zero when the current buffer can't be
|
||||||
|
@@ -1681,7 +1687,8 @@ EXTERN char e_readerrf[] INIT(= N_("E47: Error while reading errorfile"));
|
||||||
|
EXTERN char e_sandbox[] INIT(= N_("E48: Not allowed in sandbox"));
|
||||||
|
#endif
|
||||||
|
EXTERN char e_secure[] INIT(= N_("E523: Not allowed here"));
|
||||||
|
-EXTERN char e_textlock[] INIT(= N_("E565: Not allowed to change text here"));
|
||||||
|
+EXTERN char e_textlock[] INIT(= N_("E578: Not allowed to change text here"));
|
||||||
|
+EXTERN char e_textwinlock[] INIT(= N_("E565: Not allowed to change text or change window"));
|
||||||
|
#if defined(AMIGA) || defined(MACOS_X) || defined(MSWIN) \
|
||||||
|
|| defined(UNIX) || defined(VMS)
|
||||||
|
EXTERN char e_screenmode[] INIT(= N_("E359: Screen mode setting not supported"));
|
||||||
|
diff --git a/src/indent.c b/src/indent.c
|
||||||
|
index 10c82d8..a1d4d36 100644
|
||||||
|
--- a/src/indent.c
|
||||||
|
+++ b/src/indent.c
|
||||||
|
@@ -1760,7 +1760,7 @@ get_expr_indent(void)
|
||||||
|
set_vim_var_nr(VV_LNUM, curwin->w_cursor.lnum);
|
||||||
|
if (use_sandbox)
|
||||||
|
++sandbox;
|
||||||
|
- ++textlock;
|
||||||
|
+ ++textwinlock;
|
||||||
|
|
||||||
|
// Need to make a copy, the 'indentexpr' option could be changed while
|
||||||
|
// evaluating it.
|
||||||
|
@@ -1773,7 +1773,7 @@ get_expr_indent(void)
|
||||||
|
|
||||||
|
if (use_sandbox)
|
||||||
|
--sandbox;
|
||||||
|
- --textlock;
|
||||||
|
+ --textwinlock;
|
||||||
|
|
||||||
|
// Restore the cursor position so that 'indentexpr' doesn't need to.
|
||||||
|
// Pretend to be in Insert mode, allow cursor past end of line for "o"
|
||||||
|
diff --git a/src/insexpand.c b/src/insexpand.c
|
||||||
|
index 48ab260..bd809b0 100644
|
||||||
|
--- a/src/insexpand.c
|
||||||
|
+++ b/src/insexpand.c
|
||||||
|
@@ -989,9 +989,9 @@ trigger_complete_changed_event(int cur)
|
||||||
|
dict_set_items_ro(v_event);
|
||||||
|
|
||||||
|
recursive = TRUE;
|
||||||
|
- textlock++;
|
||||||
|
+ textwinlock++;
|
||||||
|
apply_autocmds(EVENT_COMPLETECHANGED, NULL, NULL, FALSE, curbuf);
|
||||||
|
- textlock--;
|
||||||
|
+ textwinlock--;
|
||||||
|
recursive = FALSE;
|
||||||
|
|
||||||
|
dict_free_contents(v_event);
|
||||||
|
@@ -2217,7 +2217,8 @@ expand_by_function(
|
||||||
|
pos = curwin->w_cursor;
|
||||||
|
curwin_save = curwin;
|
||||||
|
curbuf_save = curbuf;
|
||||||
|
- // Lock the text to avoid weird things from happening.
|
||||||
|
+ // Lock the text to avoid weird things from happening. Do allow switching
|
||||||
|
+ // to another window temporarily.
|
||||||
|
++textlock;
|
||||||
|
|
||||||
|
// Call a function, which returns a list or dict.
|
||||||
|
@@ -2442,8 +2443,8 @@ f_complete(typval_T *argvars, typval_T *rettv UNUSED)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
- // "textlock" is set when evaluating 'completefunc' but we can change text
|
||||||
|
- // here.
|
||||||
|
+ // "textlock" is set when evaluating 'completefunc' but we can change
|
||||||
|
+ // text here.
|
||||||
|
textlock = 0;
|
||||||
|
|
||||||
|
// Check for undo allowed here, because if something was already inserted
|
||||||
|
diff --git a/src/map.c b/src/map.c
|
||||||
|
index 85c46a5..2e20d40 100644
|
||||||
|
--- a/src/map.c
|
||||||
|
+++ b/src/map.c
|
||||||
|
@@ -1570,14 +1570,14 @@ eval_map_expr(
|
||||||
|
|
||||||
|
// Forbid changing text or using ":normal" to avoid most of the bad side
|
||||||
|
// effects. Also restore the cursor position.
|
||||||
|
- ++textlock;
|
||||||
|
+ ++textwinlock;
|
||||||
|
++ex_normal_lock;
|
||||||
|
set_vim_var_char(c); // set v:char to the typed character
|
||||||
|
save_cursor = curwin->w_cursor;
|
||||||
|
save_msg_col = msg_col;
|
||||||
|
save_msg_row = msg_row;
|
||||||
|
p = eval_to_string(expr, NULL, FALSE);
|
||||||
|
- --textlock;
|
||||||
|
+ --textwinlock;
|
||||||
|
--ex_normal_lock;
|
||||||
|
curwin->w_cursor = save_cursor;
|
||||||
|
msg_col = save_msg_col;
|
||||||
|
diff --git a/src/proto/ex_getln.pro b/src/proto/ex_getln.pro
|
||||||
|
index a8ca7af..f64bb1f 100644
|
||||||
|
--- a/src/proto/ex_getln.pro
|
||||||
|
+++ b/src/proto/ex_getln.pro
|
||||||
|
@@ -3,9 +3,10 @@ void cmdline_init(void);
|
||||||
|
char_u *getcmdline(int firstc, long count, int indent, int do_concat);
|
||||||
|
char_u *getcmdline_prompt(int firstc, char_u *prompt, int attr, int xp_context, char_u *xp_arg);
|
||||||
|
int check_opt_wim(void);
|
||||||
|
-int text_locked(void);
|
||||||
|
+int text_and_win_locked(void);
|
||||||
|
void text_locked_msg(void);
|
||||||
|
char *get_text_locked_msg(void);
|
||||||
|
+int text_locked(void);
|
||||||
|
int curbuf_locked(void);
|
||||||
|
int allbuf_locked(void);
|
||||||
|
char_u *getexline(int c, void *cookie, int indent, int do_concat);
|
||||||
|
diff --git a/src/register.c b/src/register.c
|
||||||
|
index 2ad136b..e56149f 100644
|
||||||
|
--- a/src/register.c
|
||||||
|
+++ b/src/register.c
|
||||||
|
@@ -932,9 +932,9 @@ yank_do_autocmd(oparg_T *oap, yankreg_T *reg)
|
||||||
|
dict_set_items_ro(v_event);
|
||||||
|
|
||||||
|
recursive = TRUE;
|
||||||
|
- textlock++;
|
||||||
|
+ textwinlock++;
|
||||||
|
apply_autocmds(EVENT_TEXTYANKPOST, NULL, NULL, FALSE, curbuf);
|
||||||
|
- textlock--;
|
||||||
|
+ textwinlock--;
|
||||||
|
recursive = FALSE;
|
||||||
|
|
||||||
|
// Empty the dictionary, v:event is still valid
|
||||||
|
diff --git a/src/testdir/test_edit.vim b/src/testdir/test_edit.vim
|
||||||
|
index a9ba31d..f0bf5cc 100644
|
||||||
|
--- a/src/testdir/test_edit.vim
|
||||||
|
+++ b/src/testdir/test_edit.vim
|
||||||
|
@@ -927,7 +927,7 @@ func Test_edit_completefunc_delete()
|
||||||
|
set completefunc=CompleteFunc
|
||||||
|
call setline(1, ['', 'abcd', ''])
|
||||||
|
2d
|
||||||
|
- call assert_fails("normal 2G$a\<C-X>\<C-U>", 'E565:')
|
||||||
|
+ call assert_fails("normal 2G$a\<C-X>\<C-U>", 'E578:')
|
||||||
|
bwipe!
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
diff --git a/src/testdir/test_popup.vim b/src/testdir/test_popup.vim
|
||||||
|
index 9890377..c7229fc 100644
|
||||||
|
--- a/src/testdir/test_popup.vim
|
||||||
|
+++ b/src/testdir/test_popup.vim
|
||||||
|
@@ -342,7 +342,7 @@ func Test_completefunc_opens_new_window_one()
|
||||||
|
setlocal completefunc=DummyCompleteOne
|
||||||
|
call setline(1, 'one')
|
||||||
|
/^one
|
||||||
|
- call assert_fails('call feedkeys("A\<C-X>\<C-U>\<C-N>\<Esc>", "x")', 'E565:')
|
||||||
|
+ call assert_fails('call feedkeys("A\<C-X>\<C-U>\<C-N>\<Esc>", "x")', 'E578:')
|
||||||
|
call assert_equal(winid, win_getid())
|
||||||
|
call assert_equal('oneDEF', getline(1))
|
||||||
|
q!
|
||||||
|
diff --git a/src/undo.c b/src/undo.c
|
||||||
|
index c11b048..4bbc0af 100644
|
||||||
|
--- a/src/undo.c
|
||||||
|
+++ b/src/undo.c
|
||||||
|
@@ -331,7 +331,7 @@ undo_allowed(void)
|
||||||
|
|
||||||
|
// Don't allow changes in the buffer while editing the cmdline. The
|
||||||
|
// caller of getcmdline() may get confused.
|
||||||
|
- if (textlock != 0)
|
||||||
|
+ if (textwinlock != 0 || textlock != 0)
|
||||||
|
{
|
||||||
|
emsg(_(e_textlock));
|
||||||
|
return FALSE;
|
||||||
|
diff --git a/src/window.c b/src/window.c
|
||||||
|
index 7c18c06..532d314 100644
|
||||||
|
--- a/src/window.c
|
||||||
|
+++ b/src/window.c
|
||||||
|
@@ -4370,7 +4370,7 @@ win_goto(win_T *wp)
|
||||||
|
|
||||||
|
if (ERROR_IF_POPUP_WINDOW)
|
||||||
|
return;
|
||||||
|
- if (text_locked())
|
||||||
|
+ if (text_and_win_locked())
|
||||||
|
{
|
||||||
|
beep_flush();
|
||||||
|
text_locked_msg();
|
||||||
|
--
|
||||||
|
1.8.3.1
|
||||||
|
|
||||||
11
vim.spec
11
vim.spec
@ -12,7 +12,7 @@
|
|||||||
Name: vim
|
Name: vim
|
||||||
Epoch: 2
|
Epoch: 2
|
||||||
Version: 8.2
|
Version: 8.2
|
||||||
Release: 36
|
Release: 37
|
||||||
Summary: Vim is a highly configurable text editor for efficiently creating and changing any kind of text.
|
Summary: Vim is a highly configurable text editor for efficiently creating and changing any kind of text.
|
||||||
License: Vim and MIT
|
License: Vim and MIT
|
||||||
URL: http://www.vim.org
|
URL: http://www.vim.org
|
||||||
@ -107,6 +107,9 @@ Patch6070: backport-CVE-2022-1619.patch
|
|||||||
Patch6071: backport-CVE-2022-1733.patch
|
Patch6071: backport-CVE-2022-1733.patch
|
||||||
Patch6072: backport-CVE-2022-1735.patch
|
Patch6072: backport-CVE-2022-1735.patch
|
||||||
Patch6073: backport-CVE-2022-1796.patch
|
Patch6073: backport-CVE-2022-1796.patch
|
||||||
|
Patch6074: backport-patch-8.2.0614-get-ml_get-error-when-deleting-a-line.patch
|
||||||
|
Patch6075: backport-patch-8.2.0670-cannot-change-window-when-evaluating-.patch
|
||||||
|
Patch6076: backport-CVE-2022-1785.patch
|
||||||
|
|
||||||
Patch9000: bugfix-rm-modify-info-version.patch
|
Patch9000: bugfix-rm-modify-info-version.patch
|
||||||
|
|
||||||
@ -495,6 +498,12 @@ popd
|
|||||||
%{_mandir}/man1/evim.*
|
%{_mandir}/man1/evim.*
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Thu Jun 09 2022 renhongxun <renhongxun@h-partners.com> - 2:8.2-36
|
||||||
|
- Type:CVE
|
||||||
|
- ID:CVE-2022-1785
|
||||||
|
- SUG:NA
|
||||||
|
- DESC:fix CVE-2022-1785
|
||||||
|
|
||||||
* Thu Jun 09 2022 shixuantong <shixuantong@h-partners.com> - 2:8.2-36
|
* Thu Jun 09 2022 shixuantong <shixuantong@h-partners.com> - 2:8.2-36
|
||||||
- Type:CVE
|
- Type:CVE
|
||||||
- ID:CVE-2022-1796
|
- ID:CVE-2022-1796
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user