aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2024-04-23 08:18:42 +0800
committerGitHub <noreply@github.com>2024-04-23 08:18:42 +0800
commitd0ab67410c04b1f79b774ed73a912ceae87952f8 (patch)
tree08cdfc3a4598e333d3aa8b6a9831179106eff71c /src
parentcb2b5e2780a6de8a3f3cad84cad7318535571a68 (diff)
downloadrneovim-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.c48
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;