Fix T66631: Crash when converting objects from Curve to Mesh
authorSybren A. Stüvel <sybren@blender.org>
Wed, 10 Jul 2019 10:58:39 +0000 (12:58 +0200)
committerSybren A. Stüvel <sybren@blender.org>
Wed, 10 Jul 2019 12:13:42 +0000 (14:13 +0200)
When `BKE_mesh_new_from_object()` cannot convert an object to a mesh, it
returns `NULL`. This case was not handled at all in
`BKE_mesh_new_from_object_to_bmain()` or `curvetomesh()`, causing a
segmentation fault.

This commit fixes the segmentation fault, and leaves the curve object as
a curve object.

Reviewed By: mont29, brecht, sergey

Differential Revision: https://developer.blender.org/D5217

source/blender/blenkernel/intern/mesh_convert.c
source/blender/editors/object/object_add.c

index dd36da44b92674fb6015cc76a36a1b4b0742dbbe..fec83ebc8997e635e20aa2e3134462299923a28b 100644 (file)
@@ -1048,6 +1048,7 @@ static Mesh *mesh_new_from_curve_type_object(Object *object)
   /* BKE_mesh_from_nurbs changes the type to a mesh, check it worked. If it didn't the curve did
    * not have any segments or otherwise would have generated an empty mesh. */
   if (temp_object->type != OB_MESH) {
+    BKE_id_free(NULL, temp_object->data);
     BKE_id_free(NULL, temp_object);
     return NULL;
   }
@@ -1216,6 +1217,10 @@ Mesh *BKE_mesh_new_from_object_to_bmain(Main *bmain,
                                         bool preserve_all_data_layers)
 {
   Mesh *mesh = BKE_mesh_new_from_object(depsgraph, object, preserve_all_data_layers);
+  if (mesh == NULL) {
+    /* Unable to convert the object to a mesh. */
+    return NULL;
+  }
 
   /* Make sure mesh only points original datablocks, also increase users of materials and other
    * possibly referenced data-blocks.
index 51b40a968edaa427e5c4c05f99515ea9e0dfc76f..f8cf55933aab514bc0dd4fb6192df22e2c48cca7 100644 (file)
@@ -2036,7 +2036,13 @@ static void curvetomesh(Main *bmain, Depsgraph *depsgraph, Object *ob)
 {
   Object *object_eval = DEG_get_evaluated_object(depsgraph, ob);
   Curve *curve = ob->data;
+
   Mesh *mesh = BKE_mesh_new_from_object_to_bmain(bmain, depsgraph, object_eval, true);
+  if (mesh == NULL) {
+    /* Unable to convert the curve to a mesh. */
+    return;
+  }
+
   BKE_object_free_modifiers(ob, 0);
   /* Replace curve used by the object itself. */
   ob->data = mesh;
@@ -2125,7 +2131,7 @@ static Base *duplibase_for_convert(
 static int convert_exec(bContext *C, wmOperator *op)
 {
   Main *bmain = CTX_data_main(C);
-  Depsgraph *depsgraph = CTX_data_depsgraph(C);
+  Depsgraph *depsgraph = CTX_data_evaluated_depsgraph(C);
   Scene *scene = CTX_data_scene(C);
   ViewLayer *view_layer = CTX_data_view_layer(C);
   Base *basen = NULL, *basact = NULL;
@@ -2344,8 +2350,9 @@ static int convert_exec(bContext *C, wmOperator *op)
       BKE_curve_curve_dimension_update(cu);
 
       if (target == OB_MESH) {
+        /* No assumption should be made that the resulting objects is a mesh, as conversion can
+         * fail. */
         curvetomesh(bmain, depsgraph, newob);
-
         /* meshes doesn't use displist */
         BKE_object_free_curve_cache(newob);
       }
@@ -2368,8 +2375,9 @@ static int convert_exec(bContext *C, wmOperator *op)
           newob = ob;
         }
 
+        /* No assumption should be made that the resulting objects is a mesh, as conversion can
+         * fail. */
         curvetomesh(bmain, depsgraph, newob);
-
         /* meshes doesn't use displist */
         BKE_object_free_curve_cache(newob);
       }