diff options
author | Bram Moolenaar <Bram@vim.org> | 2010-07-28 18:55:02 +0200 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2010-07-28 18:55:02 +0200 |
commit | 1dba0fbb7a26205d9cbf58590baefe5e669f0fc4 (patch) | |
tree | 141fa63453e50bd3151ac235ad3e7c1d6ff4d9cd /src | |
parent | 477db060eb91dbef6698b6c69ffd560557f2f3ae (diff) | |
download | vim-git-1dba0fbb7a26205d9cbf58590baefe5e669f0fc4.tar.gz |
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.c | 17 |
1 files changed, 9 insertions, 8 deletions
diff --git a/src/eval.c b/src/eval.c index 58c89c88d..f1285ca39 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; } |