• R/O
  • SSH

vim: コミット

Mirror of the Vim source from https://github.com/vim/vim


コミットメタ情報

リビジョン165a799b4129a922e3bbd97277a06538af75b616 (tree)
日時2022-01-19 05:45:02
作者Bram Moolenaar <Bram@vim....>
コミッターBram Moolenaar

ログメッセージ

patch 8.2.4139: using freed memory in expression abbreviation

Commit: https://github.com/vim/vim/commit/94075b2b0e8e3b75334799d2c082497fbf85ffa1
Author: Bram Moolenaar <Bram@vim.org>
Date: Tue Jan 18 20:30:39 2022 +0000

patch 8.2.4139: using freed memory in expression abbreviation
Problem: Using freed memory if an expression abbreviation deletes the
abbreviation.
Solution: Do not access the pointer after evaluating the expression.

変更サマリ

差分

diff -r 3a101ad74200 -r 165a799b4129 src/map.c
--- a/src/map.c Tue Jan 18 20:00:04 2022 +0100
+++ b/src/map.c Tue Jan 18 21:45:02 2022 +0100
@@ -226,7 +226,7 @@
226226 #endif
227227 int simplified)
228228 {
229- mapblock_T *mp = ALLOC_ONE(mapblock_T);
229+ mapblock_T *mp = ALLOC_CLEAR_ONE(mapblock_T);
230230
231231 if (mp == NULL)
232232 return FAIL;
@@ -1515,6 +1515,12 @@
15151515 }
15161516 if (mp != NULL)
15171517 {
1518+ int noremap;
1519+ int silent;
1520+#ifdef FEAT_EVAL
1521+ int expr;
1522+#endif
1523+
15181524 // Found a match:
15191525 // Insert the rest of the abbreviation in typebuf.tb_buf[].
15201526 // This goes from end to start.
@@ -1567,8 +1573,14 @@
15671573 // insert the last typed char
15681574 (void)ins_typebuf(tb, 1, 0, TRUE, mp->m_silent);
15691575 }
1576+
1577+ // copy values here, calling eval_map_expr() may make "mp" invalid!
1578+ noremap = mp->m_noremap;
1579+ silent = mp->m_silent;
15701580 #ifdef FEAT_EVAL
1571- if (mp->m_expr)
1581+ expr = mp->m_expr;
1582+
1583+ if (expr)
15721584 s = eval_map_expr(mp, c);
15731585 else
15741586 #endif
@@ -1576,11 +1588,11 @@
15761588 if (s != NULL)
15771589 {
15781590 // insert the to string
1579- (void)ins_typebuf(s, mp->m_noremap, 0, TRUE, mp->m_silent);
1591+ (void)ins_typebuf(s, noremap, 0, TRUE, silent);
15801592 // no abbrev. for these chars
15811593 typebuf.tb_no_abbr_cnt += (int)STRLEN(s) + j + 1;
15821594 #ifdef FEAT_EVAL
1583- if (mp->m_expr)
1595+ if (expr)
15841596 vim_free(s);
15851597 #endif
15861598 }
@@ -1590,7 +1602,7 @@
15901602 if (has_mbyte)
15911603 len = clen; // Delete characters instead of bytes
15921604 while (len-- > 0) // delete the from string
1593- (void)ins_typebuf(tb, 1, 0, TRUE, mp->m_silent);
1605+ (void)ins_typebuf(tb, 1, 0, TRUE, silent);
15941606 return TRUE;
15951607 }
15961608 }
@@ -1601,6 +1613,7 @@
16011613 /*
16021614 * Evaluate the RHS of a mapping or abbreviations and take care of escaping
16031615 * special characters.
1616+ * Careful: after this "mp" will be invalid if the mapping was deleted.
16041617 */
16051618 char_u *
16061619 eval_map_expr(
diff -r 3a101ad74200 -r 165a799b4129 src/testdir/test_mapping.vim
--- a/src/testdir/test_mapping.vim Tue Jan 18 20:00:04 2022 +0100
+++ b/src/testdir/test_mapping.vim Tue Jan 18 21:45:02 2022 +0100
@@ -704,6 +704,11 @@
704704 mapclear
705705 endfunc
706706
707+func GetAbbrText()
708+ unabbr hola
709+ return 'hello'
710+endfunc
711+
707712 " Test for <expr> in abbreviation
708713 func Test_expr_abbr()
709714 new
@@ -719,7 +724,14 @@
719724 call assert_equal('', getline(1))
720725 unabbr <expr> hte
721726
722- close!
727+ " evaluating the expression deletes the abbreviation
728+ abbr <expr> hola GetAbbrText()
729+ call assert_equal('GetAbbrText()', maparg('hola', 'i', '1'))
730+ call feedkeys("ahola \<Esc>", 'xt')
731+ call assert_equal('hello ', getline('.'))
732+ call assert_equal('', maparg('hola', 'i', '1'))
733+
734+ bwipe!
723735 endfunc
724736
725737 " Test for storing mappings in different modes in a vimrc file
diff -r 3a101ad74200 -r 165a799b4129 src/version.c
--- a/src/version.c Tue Jan 18 20:00:04 2022 +0100
+++ b/src/version.c Tue Jan 18 21:45:02 2022 +0100
@@ -751,6 +751,8 @@
751751 static int included_patches[] =
752752 { /* Add new patch number below this line */
753753 /**/
754+ 4139,
755+/**/
754756 4138,
755757 /**/
756758 4137,
旧リポジトリブラウザで表示