mirror of
https://github.com/neovim/neovim.git
synced 2024-12-19 18:55:14 -07:00
vim-patch:9.1.0365: Crash when typing many keys with D- modifier (#28464)
Problem: Crash when typing many keys with D- modifier (after 9.1.0227).
Solution: Don't treat a 0x80 byte inside a special sequence as the start
of a special sequence (zeertzjq).
closes: vim/vim#14613
6b13e3d4e4
This commit is contained in:
parent
cb2b5e2780
commit
d0ab67410c
@ -66,12 +66,11 @@
|
||||
|
||||
/// State for adding bytes to a recording or 'showcmd'.
|
||||
typedef struct {
|
||||
int prev_c;
|
||||
uint8_t buf[MB_MAXBYTES * 3 + 4];
|
||||
int prev_c;
|
||||
size_t buflen;
|
||||
unsigned pending;
|
||||
bool in_special;
|
||||
bool in_mbyte;
|
||||
unsigned pending_special;
|
||||
unsigned pending_mbyte;
|
||||
} gotchars_state_T;
|
||||
|
||||
/// Index in scriptin
|
||||
@ -1129,27 +1128,25 @@ static bool gotchars_add_byte(gotchars_state_T *state, uint8_t byte)
|
||||
{
|
||||
int c = state->buf[state->buflen++] = byte;
|
||||
bool retval = false;
|
||||
const bool in_special = state->pending_special > 0;
|
||||
const bool in_mbyte = state->pending_mbyte > 0;
|
||||
|
||||
if (state->pending > 0) {
|
||||
state->pending--;
|
||||
}
|
||||
|
||||
if (in_special) {
|
||||
state->pending_special--;
|
||||
} else if (c == K_SPECIAL) {
|
||||
// When receiving a special key sequence, store it until we have all
|
||||
// the bytes and we can decide what to do with it.
|
||||
if ((state->pending == 0 || state->in_mbyte) && c == K_SPECIAL) {
|
||||
state->pending += 2;
|
||||
if (!state->in_mbyte) {
|
||||
state->in_special = true;
|
||||
}
|
||||
state->pending_special = 2;
|
||||
}
|
||||
|
||||
if (state->pending > 0) {
|
||||
if (state->pending_special > 0) {
|
||||
goto ret_false;
|
||||
}
|
||||
|
||||
if (!state->in_mbyte) {
|
||||
if (state->in_special) {
|
||||
state->in_special = false;
|
||||
if (in_mbyte) {
|
||||
state->pending_mbyte--;
|
||||
} else {
|
||||
if (in_special) {
|
||||
if (state->prev_c == KS_MODIFIER) {
|
||||
// When receiving a modifier, wait for the modified key.
|
||||
goto ret_false;
|
||||
@ -1159,14 +1156,11 @@ static bool gotchars_add_byte(gotchars_state_T *state, uint8_t byte)
|
||||
// When receiving a multibyte character, store it until we have all
|
||||
// the bytes, so that it won't be split between two buffer blocks,
|
||||
// and delete_buff_tail() will work properly.
|
||||
state->pending = MB_BYTE2LEN_CHECK(c) - 1;
|
||||
if (state->pending > 0) {
|
||||
state->in_mbyte = true;
|
||||
goto ret_false;
|
||||
state->pending_mbyte = MB_BYTE2LEN_CHECK(c) - 1;
|
||||
}
|
||||
} else {
|
||||
// Stored all bytes of a multibyte character.
|
||||
state->in_mbyte = false;
|
||||
|
||||
if (state->pending_mbyte > 0) {
|
||||
goto ret_false;
|
||||
}
|
||||
|
||||
retval = true;
|
||||
|
@ -236,21 +236,25 @@ func Test_map_meta_multibyte()
|
||||
endfunc
|
||||
|
||||
func Test_map_super_quotes()
|
||||
if has('gui_gtk') || has('gui_gtk3') || has("macos")
|
||||
if "\<D-j>"[-1:] == '>'
|
||||
throw 'Skipped: <D- modifier not supported'
|
||||
endif
|
||||
|
||||
imap <D-"> foo
|
||||
call feedkeys("Go-\<*D-\">-\<Esc>", "xt")
|
||||
call assert_equal("-foo-", getline('$'))
|
||||
set nomodified
|
||||
iunmap <D-">
|
||||
endif
|
||||
endfunc
|
||||
|
||||
func Test_map_super_multibyte()
|
||||
if has('gui_gtk') || has('gui_gtk3') || has("macos")
|
||||
if "\<D-j>"[-1:] == '>'
|
||||
throw 'Skipped: <D- modifier not supported'
|
||||
endif
|
||||
|
||||
imap <D-á> foo
|
||||
call assert_match('i <D-á>\s*foo', execute('imap'))
|
||||
iunmap <D-á>
|
||||
endif
|
||||
endfunc
|
||||
|
||||
func Test_abbr_after_line_join()
|
||||
|
@ -266,6 +266,19 @@ func Test_zz_recording_with_select_mode_utf8_gui()
|
||||
call Run_test_recording_with_select_mode_utf8()
|
||||
endfunc
|
||||
|
||||
func Test_recording_with_super_mod()
|
||||
if "\<D-j>"[-1:] == '>'
|
||||
throw 'Skipped: <D- modifier not supported'
|
||||
endif
|
||||
|
||||
nnoremap <D-j> <Ignore>
|
||||
let s = repeat("\<D-j>", 1000)
|
||||
" This used to crash Vim
|
||||
call feedkeys($'qr{s}q', 'tx')
|
||||
call assert_equal(s, @r)
|
||||
nunmap <D-j>
|
||||
endfunc
|
||||
|
||||
" Test for executing the last used register (@)
|
||||
func Test_last_used_exec_reg()
|
||||
" Test for the @: command
|
||||
|
Loading…
Reference in New Issue
Block a user