summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZdenek Dohnal <zdohnal@redhat.com>2021-08-04 22:30:52 +0200
committerBram Moolenaar <Bram@vim.org>2021-08-04 22:30:52 +0200
commit9fe17d473a6041e2ea85229f4fa09831d910def4 (patch)
tree15c15d4bb138f6f646a0fe480003cfe990855faa
parentf18e8a969a3414ed5e6b7159c40fe43963021ff3 (diff)
downloadvim-git-9fe17d473a6041e2ea85229f4fa09831d910def4.tar.gz
patch 8.2.3290: Vim9: compiling dict may use pointer after freev8.2.3290
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)
-rw-r--r--src/version.c2
-rw-r--r--src/vim9compile.c34
2 files changed, 23 insertions, 13 deletions
diff --git a/src/version.c b/src/version.c
index a473ca552..905bc4eec 100644
--- a/src/version.c
+++ b/src/version.c
@@ -756,6 +756,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 3290,
+/**/
3289,
/**/
3288,
diff --git a/src/vim9compile.c b/src/vim9compile.c
index a487d0065..1c6e328f0 100644
--- a/src/vim9compile.c
+++ b/src/vim9compile.c
@@ -1172,21 +1172,26 @@ generate_PUSHF(cctx_T *cctx, float_T fnumber)
/*
* Generate an ISN_PUSHS instruction.
- * Consumes "str".
+ * Consumes "*str". When freed *str is set to NULL, unless "str" is NULL.
*/
static int
-generate_PUSHS(cctx_T *cctx, char_u *str)
+generate_PUSHS(cctx_T *cctx, char_u **str)
{
isn_T *isn;
if (cctx->ctx_skip == SKIP_YES)
{
- vim_free(str);
+ if (str != NULL)
+ VIM_CLEAR(*str);
return OK;
}
if ((isn = generate_instr_type(cctx, ISN_PUSHS, &t_string)) == NULL)
+ {
+ if (str != NULL)
+ VIM_CLEAR(*str);
return FAIL;
- isn->isn_arg.string = str;
+ }
+ isn->isn_arg.string = str == NULL ? NULL : *str;
return OK;
}
@@ -2785,7 +2790,7 @@ generate_tv_PUSH(cctx_T *cctx, typval_T *tv)
tv->vval.v_blob = NULL;
break;
case VAR_STRING:
- generate_PUSHS(cctx, tv->vval.v_string);
+ generate_PUSHS(cctx, &tv->vval.v_string);
tv->vval.v_string = NULL;
break;
default:
@@ -3837,7 +3842,7 @@ compile_dict(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
key = get_literal_key(arg);
if (key == NULL)
return FAIL;
- if (generate_PUSHS(cctx, key) == FAIL)
+ if (generate_PUSHS(cctx, &key) == FAIL)
return FAIL;
}
@@ -6525,7 +6530,7 @@ compile_assign_index(
char_u *key_end = to_name_end(p + 1, TRUE);
char_u *key = vim_strnsave(p + 1, key_end - p - 1);
- r = generate_PUSHS(cctx, key);
+ r = generate_PUSHS(cctx, &key);
}
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.
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;
}
generate_NEWLIST(cctx, l->lv_len);
@@ -8520,7 +8525,7 @@ compile_catch(char_u *arg, cctx_T *cctx UNUSED)
p += len + 2 + dropped;
if (pat == NULL)
return FAIL;
- if (generate_PUSHS(cctx, pat) == FAIL)
+ if (generate_PUSHS(cctx, &pat) == FAIL)
return 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)
{
- generate_PUSHS(cctx, vim_strnsave(start, p - start));
+ char_u *val = vim_strnsave(start, p - start);
+
+ generate_PUSHS(cctx, &val);
++count;
}
p += 2;
@@ -9029,7 +9036,9 @@ compile_exec(char_u *line_arg, exarg_T *eap, cctx_T *cctx)
{
if (*skipwhite(start) != NUL)
{
- generate_PUSHS(cctx, vim_strsave(start));
+ char_u *val = vim_strsave(start);
+
+ generate_PUSHS(cctx, &val);
++count;
}
break;
@@ -9847,6 +9856,7 @@ compile_def_function(
case CMD_execute:
case CMD_echomsg:
case CMD_echoerr:
+ // TODO: "echoconsole"
line = compile_mult_expr(p, ea.cmdidx, &cctx);
break;
@@ -9885,8 +9895,6 @@ compile_def_function(
#endif
break;
- // TODO: any other commands with an expression argument?
-
case CMD_append:
case CMD_change:
case CMD_insert: