comparison src/eval.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 09377fd59b2e
children d1215fcdbca8
comparison
equal deleted inserted replaced
21219:8ad4d2754054 21220:ad13736a1783
377 377
378 /* 378 /*
379 * Skip over an expression at "*pp". 379 * Skip over an expression at "*pp".
380 * If in Vim9 script and line breaks are encountered, the lines are 380 * If in Vim9 script and line breaks are encountered, the lines are
381 * concatenated. "evalarg->eval_tofree" will be set accordingly. 381 * concatenated. "evalarg->eval_tofree" will be set accordingly.
382 * "arg" is advanced to just after the expression.
383 * "start" is set to the start of the expression, "end" to just after the end.
384 * Also when the expression is copied to allocated memory.
382 * Return FAIL for an error, OK otherwise. 385 * Return FAIL for an error, OK otherwise.
383 */ 386 */
384 int 387 int
385 skip_expr_concatenate(char_u **start, char_u **end, evalarg_T *evalarg) 388 skip_expr_concatenate(
389 char_u **arg,
390 char_u **start,
391 char_u **end,
392 evalarg_T *evalarg)
386 { 393 {
387 typval_T rettv; 394 typval_T rettv;
388 int res; 395 int res;
389 int vim9script = current_sctx.sc_version == SCRIPT_VERSION_VIM9; 396 int vim9script = current_sctx.sc_version == SCRIPT_VERSION_VIM9;
390 garray_T *gap = &evalarg->eval_ga; 397 garray_T *gap = &evalarg->eval_ga;
396 ga_init2(gap, sizeof(char_u *), 10); 403 ga_init2(gap, sizeof(char_u *), 10);
397 // leave room for "start" 404 // leave room for "start"
398 if (ga_grow(gap, 1) == OK) 405 if (ga_grow(gap, 1) == OK)
399 ++gap->ga_len; 406 ++gap->ga_len;
400 } 407 }
408 *start = *arg;
401 409
402 // Don't evaluate the expression. 410 // Don't evaluate the expression.
403 if (evalarg != NULL) 411 if (evalarg != NULL)
404 evalarg->eval_flags &= ~EVAL_EVALUATE; 412 evalarg->eval_flags &= ~EVAL_EVALUATE;
405 *end = skipwhite(*end); 413 *arg = skipwhite(*arg);
406 res = eval1(end, &rettv, evalarg); 414 res = eval1(arg, &rettv, evalarg);
415 *end = *arg;
407 if (evalarg != NULL) 416 if (evalarg != NULL)
408 evalarg->eval_flags = save_flags; 417 evalarg->eval_flags = save_flags;
409 418
410 if (vim9script 419 if (vim9script
411 && (evalarg->eval_cookie != NULL || evalarg->eval_cctx != NULL)) 420 && (evalarg->eval_cookie != NULL || evalarg->eval_cctx != NULL))
417 gap->ga_itemsize = 0; 426 gap->ga_itemsize = 0;
418 } 427 }
419 else 428 else
420 { 429 {
421 char_u *p; 430 char_u *p;
422 size_t endoff = STRLEN(*end); 431 size_t endoff = STRLEN(*arg);
423 432
424 // Line breaks encountered, concatenate all the lines. 433 // Line breaks encountered, concatenate all the lines.
425 *((char_u **)gap->ga_data) = *start; 434 *((char_u **)gap->ga_data) = *start;
426 p = ga_concat_strings(gap, ""); 435 p = ga_concat_strings(gap, "");
427 436
428 // free the lines only when using getsourceline() 437 // free the lines only when using getsourceline()
429 if (evalarg->eval_cookie != NULL) 438 if (evalarg->eval_cookie != NULL)
430 { 439 {
440 // Do not free the first line, the caller can still use it.
431 *((char_u **)gap->ga_data) = NULL; 441 *((char_u **)gap->ga_data) = NULL;
442 // Do not free the last line, "arg" points into it, free it
443 // later.
444 vim_free(evalarg->eval_tofree);
445 evalarg->eval_tofree =
446 ((char_u **)gap->ga_data)[gap->ga_len - 1];
447 ((char_u **)gap->ga_data)[gap->ga_len - 1] = NULL;
432 ga_clear_strings(gap); 448 ga_clear_strings(gap);
433 } 449 }
434 else 450 else
435 ga_clear(gap); 451 ga_clear(gap);
436 gap->ga_itemsize = 0; 452 gap->ga_itemsize = 0;
437 if (p == NULL) 453 if (p == NULL)
438 return FAIL; 454 return FAIL;
439 *start = p; 455 *start = p;
440 vim_free(evalarg->eval_tofree); 456 vim_free(evalarg->eval_tofree_lambda);
441 evalarg->eval_tofree = p; 457 evalarg->eval_tofree_lambda = p;
442 // Compute "end" relative to the end. 458 // Compute "end" relative to the end.
443 *end = *start + STRLEN(*start) - endoff; 459 *end = *start + STRLEN(*start) - endoff;
444 } 460 }
445 } 461 }
446 462
1934 { 1950 {
1935 // Going to concatenate the lines after parsing. 1951 // Going to concatenate the lines after parsing.
1936 ((char_u **)gap->ga_data)[gap->ga_len] = line; 1952 ((char_u **)gap->ga_data)[gap->ga_len] = line;
1937 ++gap->ga_len; 1953 ++gap->ga_len;
1938 } 1954 }
1939 else 1955 else if (evalarg->eval_cookie != NULL)
1940 { 1956 {
1941 vim_free(evalarg->eval_tofree); 1957 vim_free(evalarg->eval_tofree);
1942 evalarg->eval_tofree = line; 1958 evalarg->eval_tofree = line;
1943 } 1959 }
1944 return skipwhite(line); 1960 return skipwhite(line);
1960 return eval_next_line(evalarg); 1976 return eval_next_line(evalarg);
1961 return p; 1977 return p;
1962 } 1978 }
1963 1979
1964 /* 1980 /*
1965 * After using "evalarg" filled from "eap" free the memory. 1981 * After using "evalarg" filled from "eap": free the memory.
1966 */ 1982 */
1967 void 1983 void
1968 clear_evalarg(evalarg_T *evalarg, exarg_T *eap) 1984 clear_evalarg(evalarg_T *evalarg, exarg_T *eap)
1969 { 1985 {
1970 if (evalarg != NULL && evalarg->eval_tofree != NULL) 1986 if (evalarg != NULL)
1971 { 1987 {
1972 if (eap != NULL) 1988 if (evalarg->eval_tofree != NULL)
1973 { 1989 {
1974 // We may need to keep the original command line, e.g. for 1990 if (eap != NULL)
1975 // ":let" it has the variable names. But we may also need the 1991 {
1976 // new one, "nextcmd" points into it. Keep both. 1992 // We may need to keep the original command line, e.g. for
1977 vim_free(eap->cmdline_tofree); 1993 // ":let" it has the variable names. But we may also need the
1978 eap->cmdline_tofree = *eap->cmdlinep; 1994 // new one, "nextcmd" points into it. Keep both.
1979 *eap->cmdlinep = evalarg->eval_tofree; 1995 vim_free(eap->cmdline_tofree);
1980 } 1996 eap->cmdline_tofree = *eap->cmdlinep;
1981 else 1997 *eap->cmdlinep = evalarg->eval_tofree;
1982 vim_free(evalarg->eval_tofree); 1998 }
1983 evalarg->eval_tofree = NULL; 1999 else
2000 vim_free(evalarg->eval_tofree);
2001 evalarg->eval_tofree = NULL;
2002 }
2003
2004 vim_free(evalarg->eval_tofree_lambda);
2005 evalarg->eval_tofree_lambda = NULL;
1984 } 2006 }
1985 } 2007 }
1986 2008
1987 /* 2009 /*
1988 * The "evaluate" argument: When FALSE, the argument is only parsed but not 2010 * The "evaluate" argument: When FALSE, the argument is only parsed but not