mirror of
https://github.com/vim/vim.git
synced 2025-09-27 04:14:06 -04:00
patch 9.1.0365: Crash when typing many keys with D- modifier
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: #14613 Signed-off-by: zeertzjq <zeertzjq@outlook.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
committed by
Christian Brabandt
parent
22697b6179
commit
6b13e3d4e4
@@ -1286,12 +1286,11 @@ del_typebuf(int len, int offset)
|
|||||||
*/
|
*/
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
int prev_c;
|
|
||||||
char_u buf[MB_MAXBYTES * 3 + 4];
|
char_u buf[MB_MAXBYTES * 3 + 4];
|
||||||
|
int prev_c;
|
||||||
size_t buflen;
|
size_t buflen;
|
||||||
unsigned pending;
|
unsigned pending_special;
|
||||||
int in_special;
|
unsigned pending_mbyte;
|
||||||
int in_mbyte;
|
|
||||||
} gotchars_state_T;
|
} gotchars_state_T;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1303,32 +1302,29 @@ gotchars_add_byte(gotchars_state_T *state, char_u byte)
|
|||||||
{
|
{
|
||||||
int c = state->buf[state->buflen++] = byte;
|
int c = state->buf[state->buflen++] = byte;
|
||||||
int retval = FALSE;
|
int retval = FALSE;
|
||||||
|
int in_special = state->pending_special > 0;
|
||||||
|
int in_mbyte = state->pending_mbyte > 0;
|
||||||
|
|
||||||
if (state->pending > 0)
|
if (in_special)
|
||||||
state->pending--;
|
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
|
|
||||||
#ifdef FEAT_GUI
|
#ifdef FEAT_GUI
|
||||||
|| c == CSI
|
|| c == CSI
|
||||||
#endif
|
#endif
|
||||||
))
|
)
|
||||||
{
|
// When receiving a special key sequence, store it until we have all
|
||||||
state->pending += 2;
|
// the bytes and we can decide what to do with it.
|
||||||
if (!state->in_mbyte)
|
state->pending_special = 2;
|
||||||
state->in_special = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state->pending > 0)
|
if (state->pending_special > 0)
|
||||||
goto ret_false;
|
goto ret_false;
|
||||||
|
|
||||||
if (!state->in_mbyte)
|
if (in_mbyte)
|
||||||
|
state->pending_mbyte--;
|
||||||
|
else
|
||||||
{
|
{
|
||||||
if (state->in_special)
|
if (in_special)
|
||||||
{
|
{
|
||||||
state->in_special = FALSE;
|
|
||||||
if (state->prev_c == KS_MODIFIER)
|
if (state->prev_c == KS_MODIFIER)
|
||||||
// When receiving a modifier, wait for the modified key.
|
// When receiving a modifier, wait for the modified key.
|
||||||
goto ret_false;
|
goto ret_false;
|
||||||
@@ -1341,16 +1337,11 @@ gotchars_add_byte(gotchars_state_T *state, char_u byte)
|
|||||||
// When receiving a multibyte character, store it until we have all
|
// When receiving a multibyte character, store it until we have all
|
||||||
// the bytes, so that it won't be split between two buffer blocks,
|
// the bytes, so that it won't be split between two buffer blocks,
|
||||||
// and delete_buff_tail() will work properly.
|
// and delete_buff_tail() will work properly.
|
||||||
state->pending = MB_BYTE2LEN_CHECK(c) - 1;
|
state->pending_mbyte = MB_BYTE2LEN_CHECK(c) - 1;
|
||||||
if (state->pending > 0)
|
|
||||||
{
|
|
||||||
state->in_mbyte = TRUE;
|
|
||||||
goto ret_false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
// Stored all bytes of a multibyte character.
|
if (state->pending_mbyte > 0)
|
||||||
state->in_mbyte = FALSE;
|
goto ret_false;
|
||||||
|
|
||||||
retval = TRUE;
|
retval = TRUE;
|
||||||
ret_false:
|
ret_false:
|
||||||
|
@@ -248,21 +248,25 @@ func Test_map_meta_multibyte()
|
|||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
func Test_map_super_quotes()
|
func Test_map_super_quotes()
|
||||||
if has('gui_gtk') || has('gui_gtk3') || has("macos")
|
if "\<D-j>"[-1:] == '>'
|
||||||
imap <D-"> foo
|
throw 'Skipped: <D- modifier not supported'
|
||||||
call feedkeys("Go-\<*D-\">-\<Esc>", "xt")
|
|
||||||
call assert_equal("-foo-", getline('$'))
|
|
||||||
set nomodified
|
|
||||||
iunmap <D-">
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
imap <D-"> foo
|
||||||
|
call feedkeys("Go-\<*D-\">-\<Esc>", "xt")
|
||||||
|
call assert_equal("-foo-", getline('$'))
|
||||||
|
set nomodified
|
||||||
|
iunmap <D-">
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
func Test_map_super_multibyte()
|
func Test_map_super_multibyte()
|
||||||
if has('gui_gtk') || has('gui_gtk3') || has("macos")
|
if "\<D-j>"[-1:] == '>'
|
||||||
imap <D-á> foo
|
throw 'Skipped: <D- modifier not supported'
|
||||||
call assert_match('i <D-á>\s*foo', execute('imap'))
|
|
||||||
iunmap <D-á>
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
imap <D-á> foo
|
||||||
|
call assert_match('i <D-á>\s*foo', execute('imap'))
|
||||||
|
iunmap <D-á>
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
func Test_abbr_after_line_join()
|
func Test_abbr_after_line_join()
|
||||||
|
@@ -261,6 +261,19 @@ func Test_zz_recording_with_select_mode_utf8_gui()
|
|||||||
call Run_test_recording_with_select_mode_utf8()
|
call Run_test_recording_with_select_mode_utf8()
|
||||||
endfunc
|
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 (@)
|
" Test for executing the last used register (@)
|
||||||
func Test_last_used_exec_reg()
|
func Test_last_used_exec_reg()
|
||||||
" Test for the @: command
|
" Test for the @: command
|
||||||
|
@@ -704,6 +704,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
365,
|
||||||
/**/
|
/**/
|
||||||
364,
|
364,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user