vim-patch:8.2.1161: Vim9: using freed memory

Problem:    Vim9: using freed memory.
Solution:   Put pointer back in evalarg instead of freeing it.

8e2730a315

Omit eval_tofree_lambda: Vim9 script only.

N/A patches for version.c:

vim-patch:8.2.1163: build error

Problem:    Build error.
Solution:   Add missing change to globals.

6e13530ca0

Co-authored-by: Bram Moolenaar <Bram@vim.org>
This commit is contained in:
zeertzjq 2023-04-14 15:05:12 +08:00
parent 562840a2a1
commit cc7a50a9ae
3 changed files with 32 additions and 23 deletions

View File

@ -2259,21 +2259,23 @@ static int eval_func(char **const arg, evalarg_T *const evalarg, char *const nam
return ret; return ret;
} }
/// After using "evalarg" filled from "eap" free the memory. /// After using "evalarg" filled from "eap": free the memory.
void clear_evalarg(evalarg_T *evalarg, exarg_T *eap) void clear_evalarg(evalarg_T *evalarg, exarg_T *eap)
{ {
if (evalarg != NULL && evalarg->eval_tofree != NULL) { if (evalarg != NULL) {
if (eap != NULL) { if (evalarg->eval_tofree != NULL) {
// We may need to keep the original command line, e.g. for if (eap != NULL) {
// ":let" it has the variable names. But we may also need the // We may need to keep the original command line, e.g. for
// new one, "nextcmd" points into it. Keep both. // ":let" it has the variable names. But we may also need the
xfree(eap->cmdline_tofree); // new one, "nextcmd" points into it. Keep both.
eap->cmdline_tofree = *eap->cmdlinep; xfree(eap->cmdline_tofree);
*eap->cmdlinep = evalarg->eval_tofree; eap->cmdline_tofree = *eap->cmdlinep;
} else { *eap->cmdlinep = evalarg->eval_tofree;
xfree(evalarg->eval_tofree); } else {
xfree(evalarg->eval_tofree);
}
evalarg->eval_tofree = NULL;
} }
evalarg->eval_tofree = NULL;
} }
} }

View File

@ -275,7 +275,7 @@ typedef struct {
LineGetter eval_getline; LineGetter eval_getline;
void *eval_cookie; ///< argument for eval_getline() void *eval_cookie; ///< argument for eval_getline()
/// pointer to the line obtained with getsourceline() /// pointer to the last line obtained with getsourceline()
char *eval_tofree; char *eval_tofree;
} evalarg_T; } evalarg_T;

View File

@ -261,15 +261,14 @@ int get_lambda_tv(char **arg, typval_T *rettv, evalarg_T *evalarg)
partial_T *pt = NULL; partial_T *pt = NULL;
int varargs; int varargs;
int ret; int ret;
char *start = skipwhite(*arg + 1);
char *s, *e;
bool *old_eval_lavars = eval_lavars_used; bool *old_eval_lavars = eval_lavars_used;
bool eval_lavars = false; bool eval_lavars = false;
char *tofree = NULL; char *tofree = NULL;
// First, check if this is a lambda expression. "->" must exists. // First, check if this is a lambda expression. "->" must exists.
ret = get_function_args(&start, '-', NULL, NULL, NULL, true); char *s = skipwhite(*arg + 1);
if (ret == FAIL || *start != '>') { ret = get_function_args(&s, '-', NULL, NULL, NULL, true);
if (ret == FAIL || *s != '>') {
return NOTDONE; return NOTDONE;
} }
@ -292,8 +291,9 @@ int get_lambda_tv(char **arg, typval_T *rettv, evalarg_T *evalarg)
// Get the start and the end of the expression. // Get the start and the end of the expression.
*arg = skipwhite((*arg) + 1); *arg = skipwhite((*arg) + 1);
s = *arg; char *start = *arg;
ret = skip_expr(arg, evalarg); ret = skip_expr(arg, evalarg);
char *end = *arg;
if (ret == FAIL) { if (ret == FAIL) {
goto errret; goto errret;
} }
@ -303,7 +303,6 @@ int get_lambda_tv(char **arg, typval_T *rettv, evalarg_T *evalarg)
evalarg->eval_tofree = NULL; evalarg->eval_tofree = NULL;
} }
e = *arg;
*arg = skipwhite(*arg); *arg = skipwhite(*arg);
if (**arg != '}') { if (**arg != '}') {
semsg(_("E451: Expected }: %s"), *arg); semsg(_("E451: Expected }: %s"), *arg);
@ -325,11 +324,11 @@ int get_lambda_tv(char **arg, typval_T *rettv, evalarg_T *evalarg)
ga_grow(&newlines, 1); ga_grow(&newlines, 1);
// Add "return " before the expression. // Add "return " before the expression.
size_t len = (size_t)(7 + e - s + 1); size_t len = (size_t)(7 + end - start + 1);
p = xmalloc(len); p = xmalloc(len);
((char **)(newlines.ga_data))[newlines.ga_len++] = p; ((char **)(newlines.ga_data))[newlines.ga_len++] = p;
STRCPY(p, "return "); STRCPY(p, "return ");
xstrlcpy(p + 7, s, (size_t)(e - s) + 1); xstrlcpy(p + 7, start, (size_t)(end - start) + 1);
if (strstr(p + 7, "a:") == NULL) { if (strstr(p + 7, "a:") == NULL) {
// No a: variables are used for sure. // No a: variables are used for sure.
flags |= FC_NOARGS; flags |= FC_NOARGS;
@ -367,14 +366,22 @@ int get_lambda_tv(char **arg, typval_T *rettv, evalarg_T *evalarg)
} }
eval_lavars_used = old_eval_lavars; eval_lavars_used = old_eval_lavars;
xfree(tofree); if (evalarg->eval_tofree == NULL) {
evalarg->eval_tofree = tofree;
} else {
xfree(tofree);
}
return OK; return OK;
errret: errret:
ga_clear_strings(&newargs); ga_clear_strings(&newargs);
xfree(fp); xfree(fp);
xfree(pt); xfree(pt);
xfree(tofree); if (evalarg->eval_tofree == NULL) {
evalarg->eval_tofree = tofree;
} else {
xfree(tofree);
}
eval_lavars_used = old_eval_lavars; eval_lavars_used = old_eval_lavars;
return FAIL; return FAIL;
} }