diff options
author | zeertzjq <zeertzjq@outlook.com> | 2024-04-23 08:18:42 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-04-23 08:18:42 +0800 |
commit | d0ab67410c04b1f79b774ed73a912ceae87952f8 (patch) | |
tree | 08cdfc3a4598e333d3aa8b6a9831179106eff71c /src | |
parent | cb2b5e2780a6de8a3f3cad84cad7318535571a68 (diff) | |
download | rneovim-d0ab67410c04b1f79b774ed73a912ceae87952f8.tar.gz rneovim-d0ab67410c04b1f79b774ed73a912ceae87952f8.tar.bz2 rneovim-d0ab67410c04b1f79b774ed73a912ceae87952f8.zip |
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
https://github.com/vim/vim/commit/6b13e3d4e46393b3a35eed7c27ae020bcbd46a9b
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/getchar.c | 48 |
1 files changed, 21 insertions, 27 deletions
diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c index 7c12737c98..9b19644b7e 100644 --- a/src/nvim/getchar.c +++ b/src/nvim/getchar.c @@ -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--; - } - - // 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; - } + 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. + 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; - } - } else { - // Stored all bytes of a multibyte character. - state->in_mbyte = false; + state->pending_mbyte = MB_BYTE2LEN_CHECK(c) - 1; + } + + if (state->pending_mbyte > 0) { + goto ret_false; } retval = true; |