1
0
forked from aniani/vim

patch 8.2.3290: Vim9: compiling dict may use pointer after free

Problem:    Vim9: compiling dict may use pointer after free and leak memory on
            failure.
Solution:   Pass a pointer to generate_PUSHS().  (Zdenek Dohnal, closes #8699)
This commit is contained in:
Zdenek Dohnal
2021-08-04 22:30:52 +02:00
committed by Bram Moolenaar
parent f18e8a969a
commit 9fe17d473a
2 changed files with 23 additions and 13 deletions

View File

@@ -755,6 +755,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
3290,
/**/ /**/
3289, 3289,
/**/ /**/

View File

@@ -1172,21 +1172,26 @@ generate_PUSHF(cctx_T *cctx, float_T fnumber)
/* /*
* Generate an ISN_PUSHS instruction. * Generate an ISN_PUSHS instruction.
* Consumes "str". * Consumes "*str". When freed *str is set to NULL, unless "str" is NULL.
*/ */
static int static int
generate_PUSHS(cctx_T *cctx, char_u *str) generate_PUSHS(cctx_T *cctx, char_u **str)
{ {
isn_T *isn; isn_T *isn;
if (cctx->ctx_skip == SKIP_YES) if (cctx->ctx_skip == SKIP_YES)
{ {
vim_free(str); if (str != NULL)
VIM_CLEAR(*str);
return OK; return OK;
} }
if ((isn = generate_instr_type(cctx, ISN_PUSHS, &t_string)) == NULL) if ((isn = generate_instr_type(cctx, ISN_PUSHS, &t_string)) == NULL)
{
if (str != NULL)
VIM_CLEAR(*str);
return FAIL; return FAIL;
isn->isn_arg.string = str; }
isn->isn_arg.string = str == NULL ? NULL : *str;
return OK; return OK;
} }
@@ -2785,7 +2790,7 @@ generate_tv_PUSH(cctx_T *cctx, typval_T *tv)
tv->vval.v_blob = NULL; tv->vval.v_blob = NULL;
break; break;
case VAR_STRING: case VAR_STRING:
generate_PUSHS(cctx, tv->vval.v_string); generate_PUSHS(cctx, &tv->vval.v_string);
tv->vval.v_string = NULL; tv->vval.v_string = NULL;
break; break;
default: default:
@@ -3837,7 +3842,7 @@ compile_dict(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
key = get_literal_key(arg); key = get_literal_key(arg);
if (key == NULL) if (key == NULL)
return FAIL; return FAIL;
if (generate_PUSHS(cctx, key) == FAIL) if (generate_PUSHS(cctx, &key) == FAIL)
return FAIL; return FAIL;
} }
@@ -6525,7 +6530,7 @@ compile_assign_index(
char_u *key_end = to_name_end(p + 1, TRUE); char_u *key_end = to_name_end(p + 1, TRUE);
char_u *key = vim_strnsave(p + 1, key_end - p - 1); char_u *key = vim_strnsave(p + 1, key_end - p - 1);
r = generate_PUSHS(cctx, key); r = generate_PUSHS(cctx, &key);
} }
return r; return r;
} }
@@ -6811,7 +6816,7 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
// Push each line and the create the list. // Push each line and the create the list.
FOR_ALL_LIST_ITEMS(l, li) FOR_ALL_LIST_ITEMS(l, li)
{ {
generate_PUSHS(cctx, li->li_tv.vval.v_string); generate_PUSHS(cctx, &li->li_tv.vval.v_string);
li->li_tv.vval.v_string = NULL; li->li_tv.vval.v_string = NULL;
} }
generate_NEWLIST(cctx, l->lv_len); generate_NEWLIST(cctx, l->lv_len);
@@ -8520,7 +8525,7 @@ compile_catch(char_u *arg, cctx_T *cctx UNUSED)
p += len + 2 + dropped; p += len + 2 + dropped;
if (pat == NULL) if (pat == NULL)
return FAIL; return FAIL;
if (generate_PUSHS(cctx, pat) == FAIL) if (generate_PUSHS(cctx, &pat) == FAIL)
return FAIL; return FAIL;
if (generate_COMPARE(cctx, EXPR_MATCH, FALSE) == FAIL) if (generate_COMPARE(cctx, EXPR_MATCH, FALSE) == FAIL)
@@ -9008,7 +9013,9 @@ compile_exec(char_u *line_arg, exarg_T *eap, cctx_T *cctx)
{ {
if (p > start) if (p > start)
{ {
generate_PUSHS(cctx, vim_strnsave(start, p - start)); char_u *val = vim_strnsave(start, p - start);
generate_PUSHS(cctx, &val);
++count; ++count;
} }
p += 2; p += 2;
@@ -9029,7 +9036,9 @@ compile_exec(char_u *line_arg, exarg_T *eap, cctx_T *cctx)
{ {
if (*skipwhite(start) != NUL) if (*skipwhite(start) != NUL)
{ {
generate_PUSHS(cctx, vim_strsave(start)); char_u *val = vim_strsave(start);
generate_PUSHS(cctx, &val);
++count; ++count;
} }
break; break;
@@ -9847,6 +9856,7 @@ compile_def_function(
case CMD_execute: case CMD_execute:
case CMD_echomsg: case CMD_echomsg:
case CMD_echoerr: case CMD_echoerr:
// TODO: "echoconsole"
line = compile_mult_expr(p, ea.cmdidx, &cctx); line = compile_mult_expr(p, ea.cmdidx, &cctx);
break; break;
@@ -9885,8 +9895,6 @@ compile_def_function(
#endif #endif
break; break;
// TODO: any other commands with an expression argument?
case CMD_append: case CMD_append:
case CMD_change: case CMD_change:
case CMD_insert: case CMD_insert: