To: vim_dev@googlegroups.com Subject: Patch 9.0.1052 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 9.0.1052 Problem: Using freed memory on exit when EXITFREE is defined. Solution: Make a deep copy of the type. Make sure TTFLAG_STATIC is not set in the copy. Files: src/vim9type.c *** ../vim-9.0.1051/src/vim9type.c 2022-12-12 18:56:27.877463284 +0000 --- src/vim9type.c 2022-12-13 13:40:59.223860093 +0000 *************** *** 57,62 **** --- 57,63 ---- if (copy == NULL) return type; *copy = *type; + copy->tt_flags &= ~TTFLAG_STATIC; if (type->tt_args != NULL && func_type_add_arg_types(copy, type->tt_argcount, type_gap) == OK) *************** *** 66,71 **** --- 67,120 ---- return copy; } + /* + * Inner part of copy_type_deep(). + * When allocation fails returns "type". + */ + static type_T * + copy_type_deep_rec(type_T *type, garray_T *type_gap, garray_T *seen_types) + { + for (int i = 0; i < seen_types->ga_len; ++i) + if (((type_T **)seen_types->ga_data)[i * 2] == type) + // seen this type before, return the copy we made + return ((type_T **)seen_types->ga_data)[i * 2 + 1]; + + type_T *copy = copy_type(type, type_gap); + if (ga_grow(seen_types, 1) == FAIL) + return copy; + ((type_T **)seen_types->ga_data)[seen_types->ga_len * 2] = type; + ((type_T **)seen_types->ga_data)[seen_types->ga_len * 2 + 1] = copy; + ++seen_types->ga_len; + + if (copy->tt_member != NULL) + copy->tt_member = copy_type_deep_rec(copy->tt_member, + type_gap, seen_types); + + if (type->tt_args != NULL) + for (int i = 0; i < type->tt_argcount; ++i) + copy->tt_args[i] = copy_type_deep_rec(copy->tt_args[i], + type_gap, seen_types); + + return copy; + } + + /* + * Make a deep copy of "type". + * When allocation fails returns "type". + */ + static type_T * + copy_type_deep(type_T *type, garray_T *type_gap) + { + garray_T seen_types; + // stores type pairs : a type we have seen and the copy used + ga_init2(&seen_types, sizeof(type_T *) * 2, 20); + + type_T *res = copy_type_deep_rec(type, type_gap, &seen_types); + + ga_clear(&seen_types); + return res; + } + void clear_type_list(garray_T *gap) { *************** *** 404,410 **** || (flags & TVTT_MORE_SPECIFIC) == 0 || l->lv_type->tt_member != &t_any)) // make a copy, lv_type may be freed if the list is freed ! return copy_type(l->lv_type, type_gap); if (l->lv_first == &range_list_item) return &t_list_number; if (l->lv_copyID == copyID) --- 453,459 ---- || (flags & TVTT_MORE_SPECIFIC) == 0 || l->lv_type->tt_member != &t_any)) // make a copy, lv_type may be freed if the list is freed ! return copy_type_deep(l->lv_type, type_gap); if (l->lv_first == &range_list_item) return &t_list_number; if (l->lv_copyID == copyID) *** ../vim-9.0.1051/src/version.c 2022-12-13 12:26:04.855054169 +0000 --- src/version.c 2022-12-13 13:42:05.447546705 +0000 *************** *** 697,698 **** --- 697,700 ---- { /* Add new patch number below this line */ + /**/ + 1052, /**/ -- DINGO: You must spank her well and after you have spanked her you may deal with her as you like and then ... spank me. AMAZING: And spank me! STUNNER: And me. LOVELY: And me. "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// \\\ \\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///