comparison src/vim9class.c @ 33471:baa62f464436 v9.0.1988

patch 9.0.1988: Vim9: potential use-after-free for class members Commit: https://github.com/vim/vim/commit/d2f4800099733216e28d59e1a5710f624b0d9ec1 Author: Yegappan Lakshmanan <yegappan@yahoo.com> Date: Thu Oct 5 20:24:18 2023 +0200 patch 9.0.1988: Vim9: potential use-after-free for class members Problem: Vim9: potential use-after-free for class members Solution: Use the class-related grow array for storing the member type instead of using a temporary type list grow array Use the type list grow array associated with the class than using a temporary type list grow array to allocate the class member type. For simple types, a predefined type is used. For complex types, the type is dynamically allocated from a grow array. For class variables, the type grow array in the class should be used. So that the lifetime of the type is same as the lifetime of the class. closes: #13279 Signed-off-by: Christian Brabandt <cb@256bit.org> Co-authored-by: Yegappan Lakshmanan <yegappan@yahoo.com>
author Christian Brabandt <cb@256bit.org>
date Thu, 05 Oct 2023 20:30:11 +0200
parents 4a62e78803db
children 156d07bea2ac
comparison
equal deleted inserted replaced
33470:1b695abea96b 33471:baa62f464436
1150 /* 1150 /*
1151 * Add class members to a new class. Allocate a typval for each class member 1151 * Add class members to a new class. Allocate a typval for each class member
1152 * and initialize it. 1152 * and initialize it.
1153 */ 1153 */
1154 static void 1154 static void
1155 add_class_members(class_T *cl, exarg_T *eap) 1155 add_class_members(class_T *cl, exarg_T *eap, garray_T *type_list_gap)
1156 { 1156 {
1157 garray_T type_list;
1158
1159 ga_init2(&type_list, sizeof(type_T *), 10);
1160
1161 // Allocate a typval for each class member and initialize it. 1157 // Allocate a typval for each class member and initialize it.
1162 cl->class_members_tv = ALLOC_CLEAR_MULT(typval_T, 1158 cl->class_members_tv = ALLOC_CLEAR_MULT(typval_T,
1163 cl->class_class_member_count); 1159 cl->class_class_member_count);
1164 if (cl->class_members_tv == NULL) 1160 if (cl->class_members_tv == NULL)
1165 return; 1161 return;
1176 if (m->ocm_type->tt_type == VAR_ANY 1172 if (m->ocm_type->tt_type == VAR_ANY
1177 && !m->ocm_has_type 1173 && !m->ocm_has_type
1178 && etv->v_type != VAR_SPECIAL) 1174 && etv->v_type != VAR_SPECIAL)
1179 // If the member variable type is not yet set, then use 1175 // If the member variable type is not yet set, then use
1180 // the initialization expression type. 1176 // the initialization expression type.
1181 m->ocm_type = typval2type(etv, get_copyID(), &type_list, 1177 m->ocm_type = typval2type(etv, get_copyID(),
1182 TVTT_DO_MEMBER|TVTT_MORE_SPECIFIC); 1178 type_list_gap,
1179 TVTT_DO_MEMBER|TVTT_MORE_SPECIFIC);
1183 *tv = *etv; 1180 *tv = *etv;
1184 vim_free(etv); 1181 vim_free(etv);
1185 } 1182 }
1186 } 1183 }
1187 else 1184 else
1189 // TODO: proper default value 1186 // TODO: proper default value
1190 tv->v_type = m->ocm_type->tt_type; 1187 tv->v_type = m->ocm_type->tt_type;
1191 tv->vval.v_string = NULL; 1188 tv->vval.v_string = NULL;
1192 } 1189 }
1193 } 1190 }
1194
1195 clear_type_list(&type_list);
1196 } 1191 }
1197 1192
1198 /* 1193 /*
1199 * Add a default constructor method (new()) to the class "cl". 1194 * Add a default constructor method (new()) to the class "cl".
1200 */ 1195 */
1951 goto cleanup; 1946 goto cleanup;
1952 } 1947 }
1953 1948
1954 // Allocate a typval for each class member and initialize it. 1949 // Allocate a typval for each class member and initialize it.
1955 if (is_class && cl->class_class_member_count > 0) 1950 if (is_class && cl->class_class_member_count > 0)
1956 add_class_members(cl, eap); 1951 add_class_members(cl, eap, &type_list);
1957 1952
1958 int have_new = FALSE; 1953 int have_new = FALSE;
1959 ufunc_T *class_func = NULL; 1954 ufunc_T *class_func = NULL;
1960 for (int i = 0; i < classfunctions.ga_len; ++i) 1955 for (int i = 0; i < classfunctions.ga_len; ++i)
1961 { 1956 {