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: