diff options
author | Zdenek Dohnal <zdohnal@redhat.com> | 2021-08-04 22:30:52 +0200 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2021-08-04 22:30:52 +0200 |
commit | 9fe17d473a6041e2ea85229f4fa09831d910def4 (patch) | |
tree | 15c15d4bb138f6f646a0fe480003cfe990855faa | |
parent | f18e8a969a3414ed5e6b7159c40fe43963021ff3 (diff) | |
download | vim-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.c | 2 | ||||
-rw-r--r-- | src/vim9compile.c | 34 |
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: |