summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2022-05-30 15:23:09 +0100
committerBram Moolenaar <Bram@vim.org>2022-05-30 15:23:09 +0100
commit71223e2db87c2bf3b09aecb46266b56cda26191d (patch)
tree3fc0857560f746c12af92b0ed02e2aab8696708e
parent89b25585ccecf223ca41ca212df8ebc227fc035a (diff)
downloadvim-git-71223e2db87c2bf3b09aecb46266b56cda26191d.tar.gz
patch 8.2.5043: can open a cmdline window from a substitute expressionv8.2.5043
Problem: Can open a cmdline window from a substitute expression. Solution: Disallow opening a command line window when text or buffer is locked.
-rw-r--r--src/buffer.c7
-rw-r--r--src/ex_getln.c19
-rw-r--r--src/proto/ex_getln.pro5
-rw-r--r--src/testdir/test_substitute.vim25
-rw-r--r--src/version.c2
-rw-r--r--src/window.c5
6 files changed, 51 insertions, 12 deletions
diff --git a/src/buffer.c b/src/buffer.c
index efec431c8..e775398d0 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -2407,12 +2407,7 @@ buflist_getfile(
if (buf == curbuf)
return OK;
- if (text_locked())
- {
- text_locked_msg();
- return FAIL;
- }
- if (curbuf_locked())
+ if (text_or_buf_locked())
return FAIL;
// altfpos may be changed by getfile(), get it now
diff --git a/src/ex_getln.c b/src/ex_getln.c
index 9dadfbf2f..623bd1d49 100644
--- a/src/ex_getln.c
+++ b/src/ex_getln.c
@@ -2740,6 +2740,21 @@ get_text_locked_msg(void)
}
/*
+ * Check for text, window or buffer locked.
+ * Give an error message and return TRUE if something is locked.
+ */
+ int
+text_or_buf_locked(void)
+{
+ if (text_locked())
+ {
+ text_locked_msg();
+ return TRUE;
+ }
+ return curbuf_locked();
+}
+
+/*
* Check if "curbuf_lock" or "allbuf_lock" is set and return TRUE when it is
* and give an error message.
*/
@@ -4379,6 +4394,10 @@ open_cmdwin(void)
int save_KeyTyped;
#endif
+ // Can't do this when text or buffer is locked.
+ if (text_or_buf_locked())
+ return K_IGNORE;
+
// Can't do this recursively. Can't do it when typing a password.
if (cmdwin_type != 0
# if defined(FEAT_CRYPT) || defined(FEAT_EVAL)
diff --git a/src/proto/ex_getln.pro b/src/proto/ex_getln.pro
index 8c8bd0ebd..bcc310c7d 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, getline_opt_T 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);
void text_locked_msg(void);
char *get_text_locked_msg(void);
-int text_locked(void);
+int text_or_buf_locked(void);
int curbuf_locked(void);
int allbuf_locked(void);
char_u *getexline(int c, void *cookie, int indent, getline_opt_T options);
@@ -32,8 +33,8 @@ cmdline_info_T *get_cmdline_info(void);
void f_getcmdcompltype(typval_T *argvars, typval_T *rettv);
void f_getcmdline(typval_T *argvars, typval_T *rettv);
void f_getcmdpos(typval_T *argvars, typval_T *rettv);
-void f_setcmdpos(typval_T *argvars, typval_T *rettv);
void f_getcmdscreenpos(typval_T *argvars, typval_T *rettv);
+void f_setcmdpos(typval_T *argvars, typval_T *rettv);
void f_getcmdtype(typval_T *argvars, typval_T *rettv);
int get_cmdline_firstc(void);
int get_list_range(char_u **str, int *num1, int *num2);
diff --git a/src/testdir/test_substitute.vim b/src/testdir/test_substitute.vim
index c8df09f4e..3c87fafe7 100644
--- a/src/testdir/test_substitute.vim
+++ b/src/testdir/test_substitute.vim
@@ -1035,6 +1035,31 @@ func Test_sub_undo_change()
delfunc Repl
endfunc
+" This was opening a command line window from the expression
+func Test_sub_open_cmdline_win()
+ " the error only happens in a very specific setup, run a new Vim instance to
+ " get a clean starting point.
+ let lines =<< trim [SCRIPT]
+ norm o0000000000000000000000000000000000000000000000000000
+ func Replace()
+ norm q/
+ endfunc
+ s/\%')/\=Replace()
+ redir >Xresult
+ messages
+ redir END
+ qall!
+ [SCRIPT]
+ call writefile(lines, 'Xscript')
+ if RunVim([], [], '-u NONE -S Xscript')
+ let messages = readfile('Xresult')
+ call assert_match('E565: Not allowed to change text or change window', messages[3])
+ endif
+
+ call delete('Xscript')
+ call delete('Xresult')
+endfunc
+
" Test for the 2-letter and 3-letter :substitute commands
func Test_substitute_short_cmd()
new
diff --git a/src/version.c b/src/version.c
index 18a1fdb41..a15bb3ed8 100644
--- a/src/version.c
+++ b/src/version.c
@@ -735,6 +735,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 5043,
+/**/
5042,
/**/
5041,
diff --git a/src/window.c b/src/window.c
index f2913d4a7..9b5ac9728 100644
--- a/src/window.c
+++ b/src/window.c
@@ -4585,14 +4585,11 @@ win_goto(win_T *wp)
return;
}
#endif
- if (text_locked())
+ if (text_or_buf_locked())
{
beep_flush();
- text_locked_msg();
return;
}
- if (curbuf_locked())
- return;
if (wp->w_buffer != curbuf)
reset_VIsual_and_resel();