diff options
author | Hans Goudey <h.goudey@me.com> | 2022-05-19 12:10:17 +0300 |
---|---|---|
committer | Hans Goudey <h.goudey@me.com> | 2022-05-19 12:10:17 +0300 |
commit | c88de1594ff35487259022223499b390fc4ad9b2 (patch) | |
tree | 3485dd122be22958b868d7b4e2e5ce825358ba4e /source/blender/blenkernel/intern/mesh_convert.cc | |
parent | 3ecc03c3d6b7baeee900a7ffd97fc0c2701adbc5 (diff) |
Fix T98237: Double free with curve object conversion to mesh
In some cases (when there is an evaluated curve), the conversion code
would try to free the evaluated data-block twice, because freeing the
object would free it from `data_eval` and then the data-block was freed
again explicitly. Now check if the data-block is stored in `data_eval`
before freeing `object.data` manually. This is another area that's made
more complex by the fact that we change the meaning of `object.data`
for evaluated objects. The solution is more complicated than it should
be, but it works whether or not an evaluated mesh or curve exists.
Diffstat (limited to 'source/blender/blenkernel/intern/mesh_convert.cc')
-rw-r--r-- | source/blender/blenkernel/intern/mesh_convert.cc | 9 |
1 files changed, 8 insertions, 1 deletions
diff --git a/source/blender/blenkernel/intern/mesh_convert.cc b/source/blender/blenkernel/intern/mesh_convert.cc index 0038a2aa806..0d34c8ad6b1 100644 --- a/source/blender/blenkernel/intern/mesh_convert.cc +++ b/source/blender/blenkernel/intern/mesh_convert.cc @@ -889,8 +889,15 @@ static void object_for_curve_to_mesh_free(Object *temp_object) curve.editnurb = nullptr; } - BKE_id_free(nullptr, temp_object->data); + /* Only free the final object data if it is *not* stored in the #data_eval field. This is still + * necessary because #temp_object's data could be replaced by a #Curve data-block that isn't also + * assigned to #data_eval. */ + const bool object_data_stored_in_data_eval = final_object_data == temp_object->runtime.data_eval; + BKE_id_free(nullptr, temp_object); + if (!object_data_stored_in_data_eval) { + BKE_id_free(nullptr, final_object_data); + } } /** |