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: