Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorHans Goudey <h.goudey@me.com>2022-05-19 12:10:17 +0300
committerHans Goudey <h.goudey@me.com>2022-05-19 12:10:17 +0300
commitc88de1594ff35487259022223499b390fc4ad9b2 (patch)
tree3485dd122be22958b868d7b4e2e5ce825358ba4e /source
parent3ecc03c3d6b7baeee900a7ffd97fc0c2701adbc5 (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')
-rw-r--r--source/blender/blenkernel/intern/mesh_convert.cc9
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);
+ }
}
/**