mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
Merge pull request #26358 from zeertzjq/vim-9.0.2140
vim-patch:9.0.{2140,2141,2142,2143}
This commit is contained in:
commit
c45d1e32a9
@ -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
|
// substitution into (and some extra space to avoid
|
||||||
// too many calls to xmalloc()/free()).
|
// too many calls to xmalloc()/free()).
|
||||||
*new_start_len = needed_len + 50;
|
*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_start = NUL;
|
||||||
new_end = *new_start;
|
new_end = *new_start;
|
||||||
} else {
|
} 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);
|
size_t len = strlen(*new_start);
|
||||||
needed_len += (int)len;
|
needed_len += (int)len;
|
||||||
if (needed_len > *new_start_len) {
|
if (needed_len > *new_start_len) {
|
||||||
|
size_t prev_new_start_len = (size_t)(*new_start_len);
|
||||||
*new_start_len = needed_len + 50;
|
*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));
|
*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;
|
new_end = *new_start + len;
|
||||||
}
|
}
|
||||||
|
@ -1455,7 +1455,7 @@ int do_set(char *arg, int opt_flags)
|
|||||||
} else {
|
} else {
|
||||||
char *startarg = arg; // remember for error message
|
char *startarg = arg; // remember for error message
|
||||||
const char *errmsg = NULL;
|
const char *errmsg = NULL;
|
||||||
char errbuf[80];
|
char errbuf[ERR_BUFLEN];
|
||||||
|
|
||||||
do_one_set_option(opt_flags, &arg, &did_show, errbuf, sizeof(errbuf), &errmsg);
|
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);
|
int opt_idx = findoption(name);
|
||||||
if (opt_idx < 0) {
|
if (opt_idx < 0) {
|
||||||
snprintf(errbuf, IOSIZE, _(e_unknown_option2), name);
|
snprintf(errbuf, sizeof(errbuf), _(e_unknown_option2), name);
|
||||||
return errbuf;
|
return errbuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,6 +66,7 @@ typedef struct {
|
|||||||
/// is parameterized, then the "os_errbuf" buffer is used to store the error
|
/// is parameterized, then the "os_errbuf" buffer is used to store the error
|
||||||
/// message (when it is not NULL).
|
/// message (when it is not NULL).
|
||||||
char *os_errbuf;
|
char *os_errbuf;
|
||||||
|
/// length of the error buffer
|
||||||
size_t os_errbuflen;
|
size_t os_errbuflen;
|
||||||
|
|
||||||
void *os_win;
|
void *os_win;
|
||||||
|
@ -938,6 +938,8 @@ enum {
|
|||||||
// Value for b_p_ul indicating the global value must be used.
|
// Value for b_p_ul indicating the global value must be used.
|
||||||
#define NO_LOCAL_UNDOLEVEL (-123456)
|
#define NO_LOCAL_UNDOLEVEL (-123456)
|
||||||
|
|
||||||
|
#define ERR_BUFLEN 80
|
||||||
|
|
||||||
#define SB_MAX 100000 // Maximum 'scrollback' value.
|
#define SB_MAX 100000 // Maximum 'scrollback' value.
|
||||||
|
|
||||||
#define MAX_NUMBERWIDTH 20 // used for 'numberwidth' and 'statuscolumn'
|
#define MAX_NUMBERWIDTH 20 // used for 'numberwidth' and 'statuscolumn'
|
||||||
|
@ -442,7 +442,7 @@ int check_signcolumn(win_T *wp)
|
|||||||
const char *check_stl_option(char *s)
|
const char *check_stl_option(char *s)
|
||||||
{
|
{
|
||||||
int groupdepth = 0;
|
int groupdepth = 0;
|
||||||
static char errbuf[80];
|
static char errbuf[ERR_BUFLEN];
|
||||||
|
|
||||||
while (*s) {
|
while (*s) {
|
||||||
// Check for valid keys after % sequences
|
// Check for valid keys after % sequences
|
||||||
|
@ -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,
|
// - Skip the byte if it's equal to the byte in the word,
|
||||||
// accepting that byte is always better.
|
// accepting that byte is always better.
|
||||||
n += sp->ts_curi++;
|
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];
|
c = byts[n];
|
||||||
if (soundfold && sp->ts_twordlen == 0 && c == '*') {
|
if (soundfold && sp->ts_twordlen == 0 && c == '*') {
|
||||||
// Inserting a vowel at the start of a word counts less,
|
// Inserting a vowel at the start of a word counts less,
|
||||||
|
@ -4470,11 +4470,12 @@ void tabpage_move(int nr)
|
|||||||
redraw_tabline = true;
|
redraw_tabline = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Go to another window.
|
/// Go to another window.
|
||||||
// When jumping to another buffer, stop Visual mode. Do this before
|
/// When jumping to another buffer, stop Visual mode. Do this before
|
||||||
// changing windows so we can yank the selection into the '*' register.
|
/// changing windows so we can yank the selection into the '*' register.
|
||||||
// When jumping to another window on the same buffer, adjust its cursor
|
/// (note: this may trigger ModeChanged autocommand!)
|
||||||
// position to keep the same Visual area.
|
/// 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)
|
void win_goto(win_T *wp)
|
||||||
{
|
{
|
||||||
win_T *owp = curwin;
|
win_T *owp = curwin;
|
||||||
@ -4485,11 +4486,17 @@ void win_goto(win_T *wp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (wp->w_buffer != curbuf) {
|
if (wp->w_buffer != curbuf) {
|
||||||
|
// careful: triggers ModeChanged autocommand
|
||||||
reset_VIsual_and_resel();
|
reset_VIsual_and_resel();
|
||||||
} else if (VIsual_active) {
|
} else if (VIsual_active) {
|
||||||
wp->w_cursor = curwin->w_cursor;
|
wp->w_cursor = curwin->w_cursor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// autocommand may have made wp invalid
|
||||||
|
if (!win_valid(wp)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
win_enter(wp, true);
|
win_enter(wp, true);
|
||||||
|
|
||||||
// Conceal cursor line in previous window, unconceal in current window.
|
// Conceal cursor line in previous window, unconceal in current window.
|
||||||
|
@ -6,7 +6,6 @@ local feed = helpers.feed
|
|||||||
|
|
||||||
before_each(clear)
|
before_each(clear)
|
||||||
|
|
||||||
-- oldtest: Test_crash1()
|
|
||||||
it('no crash when ending Visual mode while editing buffer closes window', function()
|
it('no crash when ending Visual mode while editing buffer closes window', function()
|
||||||
command('new')
|
command('new')
|
||||||
command('autocmd ModeChanged v:n ++once close')
|
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')
|
command('enew')
|
||||||
assert_alive()
|
assert_alive()
|
||||||
end)
|
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)
|
||||||
|
@ -801,9 +801,4 @@ describe('messages', function()
|
|||||||
]])
|
]])
|
||||||
os.remove('b.txt')
|
os.remove('b.txt')
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it('no crash when truncating overlong message', function()
|
|
||||||
pcall(command, 'source test/old/testdir/crash/vim_msg_trunc_poc')
|
|
||||||
assert_alive()
|
|
||||||
end)
|
|
||||||
end)
|
end)
|
||||||
|
1
test/old/testdir/crash/poc_did_set_langmap
Normal file
1
test/old/testdir/crash/poc_did_set_langmap
Normal file
@ -0,0 +1 @@
|
|||||||
|
se lmap=°xÿ7sil;drlmap=°xÿ7sil;drmo: pm313"
|
BIN
test/old/testdir/crash/poc_ex_substitute
Normal file
BIN
test/old/testdir/crash/poc_ex_substitute
Normal file
Binary file not shown.
BIN
test/old/testdir/crash/poc_suggest_trie_walk
Normal file
BIN
test/old/testdir/crash/poc_suggest_trie_walk
Normal file
Binary file not shown.
BIN
test/old/testdir/crash/poc_win_enter_ext
Normal file
BIN
test/old/testdir/crash/poc_win_enter_ext
Normal file
Binary file not shown.
@ -117,7 +117,7 @@ func Test_crash1_2()
|
|||||||
" The following used to crash Vim
|
" The following used to crash Vim
|
||||||
let opts = #{cmd: 'sh'}
|
let opts = #{cmd: 'sh'}
|
||||||
let vim = GetVimProg()
|
let vim = GetVimProg()
|
||||||
let result = 'X_crash1_1_result.txt'
|
let result = 'X_crash1_2_result.txt'
|
||||||
|
|
||||||
let buf = RunVimInTerminal('sh', opts)
|
let buf = RunVimInTerminal('sh', opts)
|
||||||
|
|
||||||
@ -128,6 +128,38 @@ func Test_crash1_2()
|
|||||||
\ ' && echo "crash 1: [OK]" > '.. result .. "\<cr>")
|
\ ' && echo "crash 1: [OK]" > '.. result .. "\<cr>")
|
||||||
call TermWait(buf, 150)
|
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
|
" clean up
|
||||||
exe buf .. "bw!"
|
exe buf .. "bw!"
|
||||||
|
|
||||||
@ -135,6 +167,9 @@ func Test_crash1_2()
|
|||||||
|
|
||||||
let expected = [
|
let expected = [
|
||||||
\ 'crash 1: [OK]',
|
\ 'crash 1: [OK]',
|
||||||
|
\ 'crash 2: [OK]',
|
||||||
|
\ 'crash 3: [OK]',
|
||||||
|
\ 'crash 4: [OK]',
|
||||||
\ ]
|
\ ]
|
||||||
|
|
||||||
call assert_equal(expected, getline(1, '$'))
|
call assert_equal(expected, getline(1, '$'))
|
||||||
|
Loading…
Reference in New Issue
Block a user