Mercurial > vim
comparison src/vim9compile.c @ 25507:1ac82ad3ee01 v8.2.3290
patch 8.2.3290: Vim9: compiling dict may use pointer after free
Commit: https://github.com/vim/vim/commit/9fe17d473a6041e2ea85229f4fa09831d910def4
Author: Zdenek Dohnal <zdohnal@redhat.com>
Date: Wed Aug 4 22:30:52 2021 +0200
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)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Wed, 04 Aug 2021 22:45:04 +0200 |
parents | 0160aff01c32 |
children | f7db86111acd |
comparison
equal
deleted
inserted
replaced
25506:743c0fa9dd79 | 25507:1ac82ad3ee01 |
---|---|
1170 } | 1170 } |
1171 #endif | 1171 #endif |
1172 | 1172 |
1173 /* | 1173 /* |
1174 * Generate an ISN_PUSHS instruction. | 1174 * Generate an ISN_PUSHS instruction. |
1175 * Consumes "str". | 1175 * Consumes "*str". When freed *str is set to NULL, unless "str" is NULL. |
1176 */ | 1176 */ |
1177 static int | 1177 static int |
1178 generate_PUSHS(cctx_T *cctx, char_u *str) | 1178 generate_PUSHS(cctx_T *cctx, char_u **str) |
1179 { | 1179 { |
1180 isn_T *isn; | 1180 isn_T *isn; |
1181 | 1181 |
1182 if (cctx->ctx_skip == SKIP_YES) | 1182 if (cctx->ctx_skip == SKIP_YES) |
1183 { | 1183 { |
1184 vim_free(str); | 1184 if (str != NULL) |
1185 VIM_CLEAR(*str); | |
1185 return OK; | 1186 return OK; |
1186 } | 1187 } |
1187 if ((isn = generate_instr_type(cctx, ISN_PUSHS, &t_string)) == NULL) | 1188 if ((isn = generate_instr_type(cctx, ISN_PUSHS, &t_string)) == NULL) |
1188 return FAIL; | 1189 { |
1189 isn->isn_arg.string = str; | 1190 if (str != NULL) |
1191 VIM_CLEAR(*str); | |
1192 return FAIL; | |
1193 } | |
1194 isn->isn_arg.string = str == NULL ? NULL : *str; | |
1190 | 1195 |
1191 return OK; | 1196 return OK; |
1192 } | 1197 } |
1193 | 1198 |
1194 /* | 1199 /* |
2783 case VAR_BLOB: | 2788 case VAR_BLOB: |
2784 generate_PUSHBLOB(cctx, tv->vval.v_blob); | 2789 generate_PUSHBLOB(cctx, tv->vval.v_blob); |
2785 tv->vval.v_blob = NULL; | 2790 tv->vval.v_blob = NULL; |
2786 break; | 2791 break; |
2787 case VAR_STRING: | 2792 case VAR_STRING: |
2788 generate_PUSHS(cctx, tv->vval.v_string); | 2793 generate_PUSHS(cctx, &tv->vval.v_string); |
2789 tv->vval.v_string = NULL; | 2794 tv->vval.v_string = NULL; |
2790 break; | 2795 break; |
2791 default: | 2796 default: |
2792 iemsg("constant type not supported"); | 2797 iemsg("constant type not supported"); |
2793 clear_tv(tv); | 2798 clear_tv(tv); |
3835 // {'name': value}, | 3840 // {'name': value}, |
3836 // {name: value} use "name" as a literal key | 3841 // {name: value} use "name" as a literal key |
3837 key = get_literal_key(arg); | 3842 key = get_literal_key(arg); |
3838 if (key == NULL) | 3843 if (key == NULL) |
3839 return FAIL; | 3844 return FAIL; |
3840 if (generate_PUSHS(cctx, key) == FAIL) | 3845 if (generate_PUSHS(cctx, &key) == FAIL) |
3841 return FAIL; | 3846 return FAIL; |
3842 } | 3847 } |
3843 | 3848 |
3844 // Check for duplicate keys, if using string keys. | 3849 // Check for duplicate keys, if using string keys. |
3845 if (key != NULL) | 3850 if (key != NULL) |
6523 else // if (*p == '.') | 6528 else // if (*p == '.') |
6524 { | 6529 { |
6525 char_u *key_end = to_name_end(p + 1, TRUE); | 6530 char_u *key_end = to_name_end(p + 1, TRUE); |
6526 char_u *key = vim_strnsave(p + 1, key_end - p - 1); | 6531 char_u *key = vim_strnsave(p + 1, key_end - p - 1); |
6527 | 6532 |
6528 r = generate_PUSHS(cctx, key); | 6533 r = generate_PUSHS(cctx, &key); |
6529 } | 6534 } |
6530 return r; | 6535 return r; |
6531 } | 6536 } |
6532 | 6537 |
6533 /* | 6538 /* |
6809 if (cctx->ctx_skip != SKIP_YES) | 6814 if (cctx->ctx_skip != SKIP_YES) |
6810 { | 6815 { |
6811 // Push each line and the create the list. | 6816 // Push each line and the create the list. |
6812 FOR_ALL_LIST_ITEMS(l, li) | 6817 FOR_ALL_LIST_ITEMS(l, li) |
6813 { | 6818 { |
6814 generate_PUSHS(cctx, li->li_tv.vval.v_string); | 6819 generate_PUSHS(cctx, &li->li_tv.vval.v_string); |
6815 li->li_tv.vval.v_string = NULL; | 6820 li->li_tv.vval.v_string = NULL; |
6816 } | 6821 } |
6817 generate_NEWLIST(cctx, l->lv_len); | 6822 generate_NEWLIST(cctx, l->lv_len); |
6818 } | 6823 } |
6819 list_free(l); | 6824 list_free(l); |
8518 pat = vim_strnsave(tofree == NULL ? p + 1 : tofree, len); | 8523 pat = vim_strnsave(tofree == NULL ? p + 1 : tofree, len); |
8519 vim_free(tofree); | 8524 vim_free(tofree); |
8520 p += len + 2 + dropped; | 8525 p += len + 2 + dropped; |
8521 if (pat == NULL) | 8526 if (pat == NULL) |
8522 return FAIL; | 8527 return FAIL; |
8523 if (generate_PUSHS(cctx, pat) == FAIL) | 8528 if (generate_PUSHS(cctx, &pat) == FAIL) |
8524 return FAIL; | 8529 return FAIL; |
8525 | 8530 |
8526 if (generate_COMPARE(cctx, EXPR_MATCH, FALSE) == FAIL) | 8531 if (generate_COMPARE(cctx, EXPR_MATCH, FALSE) == FAIL) |
8527 return NULL; | 8532 return NULL; |
8528 | 8533 |
9006 // EXECCONCAT 5 | 9011 // EXECCONCAT 5 |
9007 for (;;) | 9012 for (;;) |
9008 { | 9013 { |
9009 if (p > start) | 9014 if (p > start) |
9010 { | 9015 { |
9011 generate_PUSHS(cctx, vim_strnsave(start, p - start)); | 9016 char_u *val = vim_strnsave(start, p - start); |
9017 | |
9018 generate_PUSHS(cctx, &val); | |
9012 ++count; | 9019 ++count; |
9013 } | 9020 } |
9014 p += 2; | 9021 p += 2; |
9015 if (compile_expr0(&p, cctx) == FAIL) | 9022 if (compile_expr0(&p, cctx) == FAIL) |
9016 return NULL; | 9023 return NULL; |
9027 p = (char_u *)strstr((char *)start, "`="); | 9034 p = (char_u *)strstr((char *)start, "`="); |
9028 if (p == NULL) | 9035 if (p == NULL) |
9029 { | 9036 { |
9030 if (*skipwhite(start) != NUL) | 9037 if (*skipwhite(start) != NUL) |
9031 { | 9038 { |
9032 generate_PUSHS(cctx, vim_strsave(start)); | 9039 char_u *val = vim_strsave(start); |
9040 | |
9041 generate_PUSHS(cctx, &val); | |
9033 ++count; | 9042 ++count; |
9034 } | 9043 } |
9035 break; | 9044 break; |
9036 } | 9045 } |
9037 } | 9046 } |
9845 case CMD_echo: | 9854 case CMD_echo: |
9846 case CMD_echon: | 9855 case CMD_echon: |
9847 case CMD_execute: | 9856 case CMD_execute: |
9848 case CMD_echomsg: | 9857 case CMD_echomsg: |
9849 case CMD_echoerr: | 9858 case CMD_echoerr: |
9859 // TODO: "echoconsole" | |
9850 line = compile_mult_expr(p, ea.cmdidx, &cctx); | 9860 line = compile_mult_expr(p, ea.cmdidx, &cctx); |
9851 break; | 9861 break; |
9852 | 9862 |
9853 case CMD_put: | 9863 case CMD_put: |
9854 ea.cmd = cmd; | 9864 ea.cmd = cmd; |
9882 #else | 9892 #else |
9883 ex_ni(&ea); | 9893 ex_ni(&ea); |
9884 line = NULL; | 9894 line = NULL; |
9885 #endif | 9895 #endif |
9886 break; | 9896 break; |
9887 | |
9888 // TODO: any other commands with an expression argument? | |
9889 | 9897 |
9890 case CMD_append: | 9898 case CMD_append: |
9891 case CMD_change: | 9899 case CMD_change: |
9892 case CMD_insert: | 9900 case CMD_insert: |
9893 case CMD_k: | 9901 case CMD_k: |