aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2023-12-02 10:56:40 +0800
committerGitHub <noreply@github.com>2023-12-02 10:56:40 +0800
commitc45d1e32a92f5027fe12038b856509efe5c158fb (patch)
tree492b01ed1fed314cf279bb84857db1527be91d19
parent387c5ba3de356ea5c5f6fe71465440abd8563d8e (diff)
parent9d7544ac4cd553c9b7c8b41926b7292c5ee85943 (diff)
downloadrneovim-c45d1e32a92f5027fe12038b856509efe5c158fb.tar.gz
rneovim-c45d1e32a92f5027fe12038b856509efe5c158fb.tar.bz2
rneovim-c45d1e32a92f5027fe12038b856509efe5c158fb.zip
Merge pull request #26358 from zeertzjq/vim-9.0.2140
vim-patch:9.0.{2140,2141,2142,2143}
-rw-r--r--src/nvim/ex_cmds.c5
-rw-r--r--src/nvim/option.c4
-rw-r--r--src/nvim/option_defs.h1
-rw-r--r--src/nvim/option_vars.h2
-rw-r--r--src/nvim/optionstr.c2
-rw-r--r--src/nvim/spellsuggest.c6
-rw-r--r--src/nvim/window.c17
-rw-r--r--test/functional/legacy/crash_spec.lua19
-rw-r--r--test/functional/legacy/messages_spec.lua5
-rw-r--r--test/old/testdir/crash/poc_did_set_langmap1
-rw-r--r--test/old/testdir/crash/poc_ex_substitutebin0 -> 135 bytes
-rw-r--r--test/old/testdir/crash/poc_suggest_trie_walkbin0 -> 100 bytes
-rw-r--r--test/old/testdir/crash/poc_win_enter_extbin0 -> 1958 bytes
-rw-r--r--test/old/testdir/test_crash.vim37
14 files changed, 83 insertions, 16 deletions
diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c
index 2c51d64972..0711d82fe5 100644
--- a/src/nvim/ex_cmds.c
+++ b/src/nvim/ex_cmds.c
@@ -3144,7 +3144,7 @@ static char *sub_grow_buf(char **new_start, int *new_start_len, int needed_len)
// substitution into (and some extra space to avoid
// too many calls to xmalloc()/free()).
*new_start_len = needed_len + 50;
- *new_start = xmalloc((size_t)(*new_start_len));
+ *new_start = xcalloc(1, (size_t)(*new_start_len));
**new_start = NUL;
new_end = *new_start;
} else {
@@ -3154,8 +3154,11 @@ static char *sub_grow_buf(char **new_start, int *new_start_len, int needed_len)
size_t len = strlen(*new_start);
needed_len += (int)len;
if (needed_len > *new_start_len) {
+ size_t prev_new_start_len = (size_t)(*new_start_len);
*new_start_len = needed_len + 50;
+ size_t added_len = (size_t)(*new_start_len) - prev_new_start_len;
*new_start = xrealloc(*new_start, (size_t)(*new_start_len));
+ memset(*new_start + prev_new_start_len, 0, added_len);
}
new_end = *new_start + len;
}
diff --git a/src/nvim/option.c b/src/nvim/option.c
index 7a7cda2fa0..ba9d1262d4 100644
--- a/src/nvim/option.c
+++ b/src/nvim/option.c
@@ -1455,7 +1455,7 @@ int do_set(char *arg, int opt_flags)
} else {
char *startarg = arg; // remember for error message
const char *errmsg = NULL;
- char errbuf[80];
+ char errbuf[ERR_BUFLEN];
do_one_set_option(opt_flags, &arg, &did_show, errbuf, sizeof(errbuf), &errmsg);
@@ -3845,7 +3845,7 @@ const char *set_option_value(const char *const name, const OptVal value, int opt
int opt_idx = findoption(name);
if (opt_idx < 0) {
- snprintf(errbuf, IOSIZE, _(e_unknown_option2), name);
+ snprintf(errbuf, sizeof(errbuf), _(e_unknown_option2), name);
return errbuf;
}
diff --git a/src/nvim/option_defs.h b/src/nvim/option_defs.h
index b2e8081a08..6d0401f319 100644
--- a/src/nvim/option_defs.h
+++ b/src/nvim/option_defs.h
@@ -66,6 +66,7 @@ typedef struct {
/// is parameterized, then the "os_errbuf" buffer is used to store the error
/// message (when it is not NULL).
char *os_errbuf;
+ /// length of the error buffer
size_t os_errbuflen;
void *os_win;
diff --git a/src/nvim/option_vars.h b/src/nvim/option_vars.h
index b0e9ff9434..66185940ca 100644
--- a/src/nvim/option_vars.h
+++ b/src/nvim/option_vars.h
@@ -938,6 +938,8 @@ enum {
// Value for b_p_ul indicating the global value must be used.
#define NO_LOCAL_UNDOLEVEL (-123456)
+#define ERR_BUFLEN 80
+
#define SB_MAX 100000 // Maximum 'scrollback' value.
#define MAX_NUMBERWIDTH 20 // used for 'numberwidth' and 'statuscolumn'
diff --git a/src/nvim/optionstr.c b/src/nvim/optionstr.c
index 0a7d77e817..544524dd42 100644
--- a/src/nvim/optionstr.c
+++ b/src/nvim/optionstr.c
@@ -442,7 +442,7 @@ int check_signcolumn(win_T *wp)
const char *check_stl_option(char *s)
{
int groupdepth = 0;
- static char errbuf[80];
+ static char errbuf[ERR_BUFLEN];
while (*s) {
// Check for valid keys after % sequences
diff --git a/src/nvim/spellsuggest.c b/src/nvim/spellsuggest.c
index bdac5aa587..efd647a5c3 100644
--- a/src/nvim/spellsuggest.c
+++ b/src/nvim/spellsuggest.c
@@ -1941,6 +1941,12 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char *fword, bool soun
// - Skip the byte if it's equal to the byte in the word,
// accepting that byte is always better.
n += sp->ts_curi++;
+
+ // break out, if we would be accessing byts buffer out of bounds
+ if (byts == slang->sl_fbyts && n >= slang->sl_fbyts_len) {
+ got_int = true;
+ break;
+ }
c = byts[n];
if (soundfold && sp->ts_twordlen == 0 && c == '*') {
// Inserting a vowel at the start of a word counts less,
diff --git a/src/nvim/window.c b/src/nvim/window.c
index 7728efde33..ef1ef89d95 100644
--- a/src/nvim/window.c
+++ b/src/nvim/window.c
@@ -4470,11 +4470,12 @@ void tabpage_move(int nr)
redraw_tabline = true;
}
-// Go to another window.
-// When jumping to another buffer, stop Visual mode. Do this before
-// changing windows so we can yank the selection into the '*' register.
-// When jumping to another window on the same buffer, adjust its cursor
-// position to keep the same Visual area.
+/// Go to another window.
+/// When jumping to another buffer, stop Visual mode. Do this before
+/// changing windows so we can yank the selection into the '*' register.
+/// (note: this may trigger ModeChanged autocommand!)
+/// When jumping to another window on the same buffer, adjust its cursor
+/// position to keep the same Visual area.
void win_goto(win_T *wp)
{
win_T *owp = curwin;
@@ -4485,11 +4486,17 @@ void win_goto(win_T *wp)
}
if (wp->w_buffer != curbuf) {
+ // careful: triggers ModeChanged autocommand
reset_VIsual_and_resel();
} else if (VIsual_active) {
wp->w_cursor = curwin->w_cursor;
}
+ // autocommand may have made wp invalid
+ if (!win_valid(wp)) {
+ return;
+ }
+
win_enter(wp, true);
// Conceal cursor line in previous window, unconceal in current window.
diff --git a/test/functional/legacy/crash_spec.lua b/test/functional/legacy/crash_spec.lua
index 5094f81847..094bea253e 100644
--- a/test/functional/legacy/crash_spec.lua
+++ b/test/functional/legacy/crash_spec.lua
@@ -6,7 +6,6 @@ local feed = helpers.feed
before_each(clear)
--- oldtest: Test_crash1()
it('no crash when ending Visual mode while editing buffer closes window', function()
command('new')
command('autocmd ModeChanged v:n ++once close')
@@ -14,3 +13,21 @@ it('no crash when ending Visual mode while editing buffer closes window', functi
command('enew')
assert_alive()
end)
+
+it('no crash when ending Visual mode close the window to switch to', function()
+ command('new')
+ command('autocmd ModeChanged v:n ++once only')
+ feed('v')
+ command('wincmd p')
+ assert_alive()
+end)
+
+it('no crash when truncating overlong message', function()
+ pcall(command, 'source test/old/testdir/crash/vim_msg_trunc_poc')
+ assert_alive()
+end)
+
+it('no crash with very long option error message', function()
+ pcall(command, 'source test/old/testdir/crash/poc_did_set_langmap')
+ assert_alive()
+end)
diff --git a/test/functional/legacy/messages_spec.lua b/test/functional/legacy/messages_spec.lua
index e0cc1dc79c..146b00acb0 100644
--- a/test/functional/legacy/messages_spec.lua
+++ b/test/functional/legacy/messages_spec.lua
@@ -801,9 +801,4 @@ describe('messages', function()
]])
os.remove('b.txt')
end)
-
- it('no crash when truncating overlong message', function()
- pcall(command, 'source test/old/testdir/crash/vim_msg_trunc_poc')
- assert_alive()
- end)
end)
diff --git a/test/old/testdir/crash/poc_did_set_langmap b/test/old/testdir/crash/poc_did_set_langmap
new file mode 100644
index 0000000000..f77145b9d1
--- /dev/null
+++ b/test/old/testdir/crash/poc_did_set_langmap
@@ -0,0 +1 @@
+se lmap=°xÿ7sil;drlmap=°xÿ7sil;drmo: pm31 3" \ No newline at end of file
diff --git a/test/old/testdir/crash/poc_ex_substitute b/test/old/testdir/crash/poc_ex_substitute
new file mode 100644
index 0000000000..bcf1286512
--- /dev/null
+++ b/test/old/testdir/crash/poc_ex_substitute
Binary files differ
diff --git a/test/old/testdir/crash/poc_suggest_trie_walk b/test/old/testdir/crash/poc_suggest_trie_walk
new file mode 100644
index 0000000000..c79b6eeb5c
--- /dev/null
+++ b/test/old/testdir/crash/poc_suggest_trie_walk
Binary files differ
diff --git a/test/old/testdir/crash/poc_win_enter_ext b/test/old/testdir/crash/poc_win_enter_ext
new file mode 100644
index 0000000000..73f53b575b
--- /dev/null
+++ b/test/old/testdir/crash/poc_win_enter_ext
Binary files differ
diff --git a/test/old/testdir/test_crash.vim b/test/old/testdir/test_crash.vim
index b093b053c5..49e712a901 100644
--- a/test/old/testdir/test_crash.vim
+++ b/test/old/testdir/test_crash.vim
@@ -117,7 +117,7 @@ func Test_crash1_2()
" The following used to crash Vim
let opts = #{cmd: 'sh'}
let vim = GetVimProg()
- let result = 'X_crash1_1_result.txt'
+ let result = 'X_crash1_2_result.txt'
let buf = RunVimInTerminal('sh', opts)
@@ -128,6 +128,38 @@ func Test_crash1_2()
\ ' && echo "crash 1: [OK]" > '.. result .. "\<cr>")
call TermWait(buf, 150)
+ let file = 'crash/poc_win_enter_ext'
+ let cmn_args = "%s -u NONE -i NONE -n -e -s -S %s -c ':qa!'"
+ let args = printf(cmn_args, vim, file)
+ call term_sendkeys(buf, args ..
+ \ ' && echo "crash 2: [OK]" >> '.. result .. "\<cr>")
+ call TermWait(buf, 350)
+
+ let file = 'crash/poc_suggest_trie_walk'
+ let cmn_args = "%s -u NONE -i NONE -n -e -s -S %s -c ':qa!'"
+ let args = printf(cmn_args, vim, file)
+ call term_sendkeys(buf, args ..
+ \ ' && echo "crash 3: [OK]" >> '.. result .. "\<cr>")
+ call TermWait(buf, 150)
+
+ let file = 'crash/poc_did_set_langmap'
+ let cmn_args = "%s -u NONE -i NONE -n -X -m -n -e -s -S %s -c ':qa!'"
+ let args = printf(cmn_args, vim, file)
+ call term_sendkeys(buf, args ..
+ \ ' ; echo "crash 4: [OK]" >> '.. result .. "\<cr>")
+ call TermWait(buf, 150)
+
+ let file = 'crash/poc_ex_substitute'
+ let cmn_args = "%s -u NONE -i NONE -n -e -s -S %s -c ':qa!'"
+ let args = printf(cmn_args, vim, file)
+ " just make sure it runs, we don't care about the resulting echo
+ call term_sendkeys(buf, args .. "\<cr>")
+ " There is no output generated in Github CI for the asan clang build.
+ " so just skip generating the ouput.
+ " call term_sendkeys(buf, args ..
+ " \ ' && echo "crash 5: [OK]" >> '.. result .. "\<cr>")
+ call TermWait(buf, 150)
+
" clean up
exe buf .. "bw!"
@@ -135,6 +167,9 @@ func Test_crash1_2()
let expected = [
\ 'crash 1: [OK]',
+ \ 'crash 2: [OK]',
+ \ 'crash 3: [OK]',
+ \ 'crash 4: [OK]',
\ ]
call assert_equal(expected, getline(1, '$'))