summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2010-01-27 17:31:43 +0100
committerBram Moolenaar <Bram@vim.org>2010-01-27 17:31:43 +0100
commit0dbf720d864782177041d276d78e4a216fd320f9 (patch)
tree9194709ad8fc46733e397e16060f4bb964deae4d
parent38ef43b262cbbea63b4ec8cadd8368314af26164 (diff)
downloadvim-git-0dbf720d864782177041d276d78e4a216fd320f9.tar.gz
updated for version 7.2.347v7.2.347
Problem: Crash when executing <expr> mapping redefines that same mapping. Solution: Save the values used before evaluating the expression.
-rw-r--r--src/getchar.c43
-rw-r--r--src/version.c2
2 files changed, 39 insertions, 6 deletions
diff --git a/src/getchar.c b/src/getchar.c
index f4ad8d2a0..99f7ddb0d 100644
--- a/src/getchar.c
+++ b/src/getchar.c
@@ -2389,6 +2389,17 @@ vgetorpeek(advance)
/* complete match */
if (keylen >= 0 && keylen <= typebuf.tb_len)
{
+#ifdef FEAT_EVAL
+ int save_m_expr;
+ int save_m_noremap;
+ int save_m_silent;
+ char_u *save_m_keys;
+ char_u *save_m_str;
+#else
+# define save_m_noremap mp->m_noremap
+# define save_m_silent mp->m_silent
+#endif
+
/* write chars to script file(s) */
if (keylen > typebuf.tb_maplen)
gotchars(typebuf.tb_buf + typebuf.tb_off
@@ -2431,6 +2442,16 @@ vgetorpeek(advance)
#endif
#ifdef FEAT_EVAL
+ /* Copy the values from *mp that are used, because
+ * evaluating the expression may invoke a function
+ * that redefines the mapping, thereby making *mp
+ * invalid. */
+ save_m_expr = mp->m_expr;
+ save_m_noremap = mp->m_noremap;
+ save_m_silent = mp->m_silent;
+ save_m_keys = NULL; /* only saved when needed */
+ save_m_str = NULL; /* only saved when needed */
+
/*
* Handle ":map <expr>": evaluate the {rhs} as an
* expression. Save and restore the typeahead so that
@@ -2446,7 +2467,9 @@ vgetorpeek(advance)
if (tabuf.typebuf_valid)
{
vgetc_busy = 0;
- s = eval_map_expr(mp->m_str, NUL);
+ save_m_keys = vim_strsave(mp->m_keys);
+ save_m_str = vim_strsave(mp->m_str);
+ s = eval_map_expr(save_m_str, NUL);
vgetc_busy = save_vgetc_busy;
}
else
@@ -2470,17 +2493,25 @@ vgetorpeek(advance)
else
{
i = ins_typebuf(s,
- mp->m_noremap != REMAP_YES
- ? mp->m_noremap
- : STRNCMP(s, mp->m_keys,
+ save_m_noremap != REMAP_YES
+ ? save_m_noremap
+ : STRNCMP(s,
+#ifdef FEAT_EVAL
+ save_m_keys != NULL ? save_m_keys :
+#endif
+ mp->m_keys,
(size_t)keylen) != 0
? REMAP_YES : REMAP_SKIP,
- 0, TRUE, cmd_silent || mp->m_silent);
+ 0, TRUE, cmd_silent || save_m_silent);
#ifdef FEAT_EVAL
- if (mp->m_expr)
+ if (save_m_expr)
vim_free(s);
#endif
}
+#ifdef FEAT_EVAL
+ vim_free(save_m_keys);
+ vim_free(save_m_str);
+#endif
if (i == FAIL)
{
c = -1;
diff --git a/src/version.c b/src/version.c
index f79e92e2e..8b9013f47 100644
--- a/src/version.c
+++ b/src/version.c
@@ -682,6 +682,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 347,
+/**/
346,
/**/
345,