]> granicus.if.org Git - vim/commitdiff
Fix: :redir to a dictionary that is changed before ":redir END" causes a
authorBram Moolenaar <Bram@vim.org>
Wed, 28 Jul 2010 16:55:02 +0000 (18:55 +0200)
committerBram Moolenaar <Bram@vim.org>
Wed, 28 Jul 2010 16:55:02 +0000 (18:55 +0200)
memory access error.

src/eval.c

index 58c89c88d19a1b6e03c71742026fbf349a9fd7c7..f1285ca392e75e2b138a7350a87d9d54f344aed0 100644 (file)
@@ -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;
     }