Fix #128169: Memory leak in bpy.data.meshes.new_from_object

Resolve leak in new_from_object when preserve_all_data_layers=True and
a sub-surfaced mesh.

A copy was made, then BKE_mesh_wrapper_ensure_subdivision would return
the "mesh_eval" of the copy, leaking the mesh passed to
BKE_mesh_wrapper_ensure_subdivision.

Ref !142176
This commit is contained in:
Campbell Barton
2025-07-17 16:44:22 +10:00
parent a3aa47ecec
commit ce5c54fef6

View File

@@ -821,8 +821,25 @@ static Mesh *mesh_new_from_mesh_object_with_layers(Depsgraph *depsgraph,
mask.lmask |= CD_MASK_ORIGINDEX;
mask.pmask |= CD_MASK_ORIGINDEX;
}
Mesh *result = blender::bke::mesh_create_eval_final(depsgraph, scene, &object_for_eval, &mask);
return (ensure_subdivision) ? BKE_mesh_wrapper_ensure_subdivision(result) : result;
if (ensure_subdivision) {
/* Returns a borrowed reference which is still owned by `result`.
* Steal the reference from `result` which can then be freed. */
Mesh *result_maybe_subdiv = BKE_mesh_wrapper_ensure_subdivision(result);
if (result != result_maybe_subdiv) {
/* Expected, but assert this is the case. */
BLI_assert(result->runtime->mesh_eval == result_maybe_subdiv);
if (result->runtime->mesh_eval == result_maybe_subdiv) {
result->runtime->mesh_eval = nullptr;
BKE_id_free(nullptr, result);
result = result_maybe_subdiv;
}
}
}
return result;
}
static Mesh *mesh_new_from_mesh_object(Depsgraph *depsgraph,