From 1d97781dc53416072387b1d71aeaf11caecd8cf0 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Wed, 27 Apr 2022 20:30:52 +0800 Subject: [PATCH] vim-patch:8.2.4833: failure of mapping not checked for Problem: Failure of mapping not checked for. Solution: Check return value of ins_typebuf(). (closes vim/vim#10299) https://github.com/vim/vim/commit/12e21e387b5bbc928097abf1c189b7dc665838fc --- src/nvim/getchar.c | 22 ++++++++++++++++++---- src/nvim/testdir/test_termcodes.vim | 5 +++-- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c index 9826317102..5aba241d45 100644 --- a/src/nvim/getchar.c +++ b/src/nvim/getchar.c @@ -1761,7 +1761,9 @@ static int put_string_in_typebuf(int offset, int slen, char_u *string, int new_s del_typebuf(-extra, offset); } else if (extra > 0) { // insert the extra space we need - ins_typebuf(string + slen, REMAP_YES, offset, false, false); + if (ins_typebuf(string + slen, REMAP_YES, offset, false, false) == FAIL) { + return FAIL; + } } // Careful: del_typebuf() and ins_typebuf() may have reallocated // typebuf.tb_buf[]! @@ -1772,7 +1774,7 @@ static int put_string_in_typebuf(int offset, int slen, char_u *string, int new_s /// Check if typebuf.tb_buf[] contains a modifer plus key that can be changed /// into just a key, apply that. /// Check from typebuf.tb_buf[typebuf.tb_off] to typebuf.tb_buf[typebuf.tb_off + "max_offset"]. -/// @return the length of the replaced bytes, zero if nothing changed. +/// @return the length of the replaced bytes, 0 if nothing changed, -1 for error. static int check_simplify_modifier(int max_offset) { for (int offset = 0; offset < max_offset; offset++) { @@ -1796,7 +1798,15 @@ static int check_simplify_modifier(int max_offset) vgetc_mod_mask = tp[2]; } char_u new_string[MB_MAXBYTES]; - int len = utf_char2bytes(new_c, new_string); + int len; + if (IS_SPECIAL(new_c)) { + new_string[0] = K_SPECIAL; + new_string[1] = (char_u)K_SECOND(new_c); + new_string[2] = (char_u)K_THIRD(new_c); + len = 3; + } else { + len = utf_char2bytes(new_c, new_string); + } if (modifier == 0) { if (put_string_in_typebuf(offset, 4, new_string, len) == FAIL) { return -1; @@ -1819,6 +1829,7 @@ static int check_simplify_modifier(int max_offset) /// - When nothing mapped and typeahead has a character: return map_result_get. /// - When there is no match yet, return map_result_nomatch, need to get more /// typeahead. +/// - On failure (out of memory) return map_result_fail. static int handle_mapping(int *keylenp, bool *timedout, int *mapdepth) { mapblock_T *mp = NULL; @@ -2032,7 +2043,10 @@ static int handle_mapping(int *keylenp, bool *timedout, int *mapdepth) } else if (keylen != KEYLEN_PART_KEY) { // Try to include the modifier into the key. keylen = check_simplify_modifier(max_mlen + 1); - assert(keylen >= 0); + if (keylen < 0) { + // ins_typebuf() failed + return map_result_fail; + } } } else { keylen = 0; diff --git a/src/nvim/testdir/test_termcodes.vim b/src/nvim/testdir/test_termcodes.vim index ecd408264d..987889f33c 100644 --- a/src/nvim/testdir/test_termcodes.vim +++ b/src/nvim/testdir/test_termcodes.vim @@ -1,8 +1,9 @@ func Test_simplify_ctrl_at() " feeding unsimplified CTRL-@ should still trigger i_CTRL-@ - call feedkeys("ifoo\A\<*C-@>", 'xt') - call assert_equal('foofoo', getline(1)) + call feedkeys("ifoo\A\<*C-@>x", 'xt') + call assert_equal('foofo', getline(1)) + bw! endfunc