summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2010-07-28 18:55:02 +0200
committerBram Moolenaar <Bram@vim.org>2010-07-28 18:55:02 +0200
commit1dba0fbb7a26205d9cbf58590baefe5e669f0fc4 (patch)
tree141fa63453e50bd3151ac235ad3e7c1d6ff4d9cd /src
parent477db060eb91dbef6698b6c69ffd560557f2f3ae (diff)
Fix: :redir to a dictionary that is changed before ":redir END" causes a
memory access error.
Diffstat (limited to 'src')
-rw-r--r--src/eval.c17
1 files changed, 9 insertions, 8 deletions
diff --git a/src/eval.c b/src/eval.c
index 58c89c88d1..f1285ca392 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -1056,6 +1056,7 @@ var_redir_start(name, append)
FNE_CHECK_START);
if (redir_endp == NULL || redir_lval->ll_name == NULL || *redir_endp != NUL)
{
+ clear_lval(redir_lval);
if (redir_endp != NULL && *redir_endp != NUL)
/* Trailing characters are present after the variable name */
EMSG(_(e_trailing));
@@ -1076,6 +1077,7 @@ var_redir_start(name, append)
set_var_lval(redir_lval, redir_endp, &tv, TRUE, (char_u *)".");
else
set_var_lval(redir_lval, redir_endp, &tv, TRUE, (char_u *)"=");
+ clear_lval(redir_lval);
err = did_emsg;
did_emsg |= save_emsg;
if (err)
@@ -1084,12 +1086,6 @@ var_redir_start(name, append)
var_redir_stop();
return FAIL;
}
- if (redir_lval->ll_newkey != NULL)
- {
- /* Dictionary item was created, don't do it again. */
- vim_free(redir_lval->ll_newkey);
- redir_lval->ll_newkey = NULL;
- }
return OK;
}
@@ -1144,14 +1140,19 @@ var_redir_stop()
ga_append(&redir_ga, NUL); /* Append the trailing NUL. */
tv.v_type = VAR_STRING;
tv.vval.v_string = redir_ga.ga_data;
- set_var_lval(redir_lval, redir_endp, &tv, FALSE, (char_u *)".");
+ /* Call get_lval() again, if it's inside a Dict or List it may
+ * have changed. */
+ redir_endp = get_lval(redir_varname, NULL, redir_lval,
+ FALSE, FALSE, FALSE, FNE_CHECK_START);
+ if (redir_endp != NULL && redir_lval->ll_name != NULL)
+ set_var_lval(redir_lval, redir_endp, &tv, FALSE, (char_u *)".");
+ clear_lval(redir_lval);
}
/* free the collected output */
vim_free(redir_ga.ga_data);
redir_ga.ga_data = NULL;
- clear_lval(redir_lval);
vim_free(redir_lval);
redir_lval = NULL;
}