Mercurial > vim
diff src/getchar.c @ 35028:59d23ae7dbb0 v9.1.0365
patch 9.1.0365: Crash when typing many keys with D- modifier
Commit: https://github.com/vim/vim/commit/6b13e3d4e46393b3a35eed7c27ae020bcbd46a9b
Author: zeertzjq <zeertzjq@outlook.com>
Date: Mon Apr 22 21:04:29 2024 +0200
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>
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Mon, 22 Apr 2024 21:15:07 +0200 |
parents | ca76febc62fc |
children |
line wrap: on
line diff
--- a/src/getchar.c +++ b/src/getchar.c @@ -1286,12 +1286,11 @@ del_typebuf(int len, int offset) */ typedef struct { + char_u buf[MB_MAXBYTES * 3 + 4]; int prev_c; - char_u buf[MB_MAXBYTES * 3 + 4]; size_t buflen; - unsigned pending; - int in_special; - int in_mbyte; + unsigned pending_special; + unsigned pending_mbyte; } gotchars_state_T; /* @@ -1303,32 +1302,29 @@ gotchars_add_byte(gotchars_state_T *stat { int c = state->buf[state->buflen++] = byte; int retval = FALSE; - - 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 + int in_special = state->pending_special > 0; + int in_mbyte = state->pending_mbyte > 0; + + if (in_special) + state->pending_special--; + else if (c == K_SPECIAL #ifdef FEAT_GUI || c == CSI #endif - )) + ) + // 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_special > 0) + goto ret_false; + + if (in_mbyte) + state->pending_mbyte--; + else { - state->pending += 2; - if (!state->in_mbyte) - state->in_special = TRUE; - } - - if (state->pending > 0) - goto ret_false; - - if (!state->in_mbyte) - { - if (state->in_special) + if (in_special) { - state->in_special = FALSE; if (state->prev_c == KS_MODIFIER) // When receiving a modifier, wait for the modified key. goto ret_false; @@ -1341,16 +1337,11 @@ gotchars_add_byte(gotchars_state_T *stat // 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; ret_false: