diff src/userfunc.c @ 21220:ad13736a1783 v8.2.1161

patch 8.2.1161: Vim9: using freed memory Commit: https://github.com/vim/vim/commit/8e2730a315b8b06192f5fc822dc218dbb3cff7ae Author: Bram Moolenaar <Bram@vim.org> Date: Wed Jul 8 22:01:49 2020 +0200 patch 8.2.1161: Vim9: using freed memory Problem: Vim9: using freed memory. Solution: Put pointer back in evalarg instead of freeing it.
author Bram Moolenaar <Bram@vim.org>
date Wed, 08 Jul 2020 22:15:04 +0200
parents 1f4d0375f947
children a4d00a2dadd6
line wrap: on
line diff
--- a/src/userfunc.c
+++ b/src/userfunc.c
@@ -389,8 +389,8 @@ get_lambda_tv(char_u **arg, typval_T *re
     partial_T   *pt = NULL;
     int		varargs;
     int		ret;
-    char_u	*start;
-    char_u	*s, *e;
+    char_u	*s;
+    char_u	*start, *end;
     int		*old_eval_lavars = eval_lavars_used;
     int		eval_lavars = FALSE;
     char_u	*tofree = NULL;
@@ -399,10 +399,10 @@ get_lambda_tv(char_u **arg, typval_T *re
     ga_init(&newlines);
 
     // First, check if this is a lambda expression. "->" must exist.
-    start = skipwhite(*arg + 1);
-    ret = get_function_args(&start, '-', NULL, NULL, NULL, NULL, TRUE,
+    s = skipwhite(*arg + 1);
+    ret = get_function_args(&s, '-', NULL, NULL, NULL, NULL, TRUE,
 								   NULL, NULL);
-    if (ret == FAIL || *start != '>')
+    if (ret == FAIL || *s != '>')
 	return NOTDONE;
 
     // Parse the arguments again.
@@ -423,8 +423,8 @@ get_lambda_tv(char_u **arg, typval_T *re
 
     // Get the start and the end of the expression.
     *arg = skipwhite_and_linebreak(*arg + 1, evalarg);
-    s = *arg;
-    ret = skip_expr_concatenate(&s, arg, evalarg);
+    start = *arg;
+    ret = skip_expr_concatenate(arg, &start, &end, evalarg);
     if (ret == FAIL)
 	goto errret;
     if (evalarg != NULL)
@@ -434,7 +434,6 @@ get_lambda_tv(char_u **arg, typval_T *re
 	evalarg->eval_tofree = NULL;
     }
 
-    e = *arg;
     *arg = skipwhite_and_linebreak(*arg, evalarg);
     if (**arg != '}')
     {
@@ -463,13 +462,13 @@ get_lambda_tv(char_u **arg, typval_T *re
 	    goto errret;
 
 	// Add "return " before the expression.
-	len = 7 + (int)(e - s) + 1;
+	len = 7 + (int)(end - start) + 1;
 	p = alloc(len);
 	if (p == NULL)
 	    goto errret;
 	((char_u **)(newlines.ga_data))[newlines.ga_len++] = p;
 	STRCPY(p, "return ");
-	vim_strncpy(p + 7, s, e - s);
+	vim_strncpy(p + 7, start, end - start);
 	if (strstr((char *)p + 7, "a:") == NULL)
 	    // No a: variables are used for sure.
 	    flags |= FC_NOARGS;
@@ -509,7 +508,10 @@ get_lambda_tv(char_u **arg, typval_T *re
     }
 
     eval_lavars_used = old_eval_lavars;
-    vim_free(tofree);
+    if (evalarg->eval_tofree == NULL)
+	evalarg->eval_tofree = tofree;
+    else
+	vim_free(tofree);
     return OK;
 
 errret:
@@ -517,7 +519,10 @@ errret:
     ga_clear_strings(&newlines);
     vim_free(fp);
     vim_free(pt);
-    vim_free(tofree);
+    if (evalarg->eval_tofree == NULL)
+	evalarg->eval_tofree = tofree;
+    else
+	vim_free(tofree);
     eval_lavars_used = old_eval_lavars;
     return FAIL;
 }