diff options
author | Hans Goudey <h.goudey@me.com> | 2022-04-16 00:55:15 +0300 |
---|---|---|
committer | Hans Goudey <h.goudey@me.com> | 2022-04-16 00:55:15 +0300 |
commit | dc5ae10692520e83277874802e42dac17f6fb95e (patch) | |
tree | 7c61a2f85645d865f46b1e35e9b38eb2589aa464 /source/blender/geometry | |
parent | cb3c233ed3a5196269f0aa626ea20c7c8aeffebf (diff) |
Fix T96988: Merge by distance node crash with certain input
If the `wpoly` vector was small, the `wpoly_new` pointer could point
to part of its inline buffer on the stack, which becomes invalid out of
that scope. Instead, store `wpoly_new` as a span, and assign it properly
from the moved vector.
Diffstat (limited to 'source/blender/geometry')
-rw-r--r-- | source/blender/geometry/intern/mesh_merge_by_distance.cc | 17 |
1 files changed, 6 insertions, 11 deletions
diff --git a/source/blender/geometry/intern/mesh_merge_by_distance.cc b/source/blender/geometry/intern/mesh_merge_by_distance.cc index 5a4366f546d..9bb1cbb324e 100644 --- a/source/blender/geometry/intern/mesh_merge_by_distance.cc +++ b/source/blender/geometry/intern/mesh_merge_by_distance.cc @@ -104,7 +104,7 @@ struct WeldMesh { /* References all polygons and loops that will be affected. */ Vector<WeldLoop> wloop; Vector<WeldPoly> wpoly; - WeldPoly *wpoly_new; + MutableSpan<WeldPoly> wpoly_new; int wloop_len; int wpoly_len; int wpoly_new_len; @@ -806,11 +806,9 @@ static void weld_poly_loop_ctx_alloc(Span<MPoly> mpoly, wpoly.resize(wpoly_len + maybe_new_poly); } - WeldPoly *poly_new = wpoly.data() + wpoly_len; - r_weld_mesh->wloop = std::move(wloop); r_weld_mesh->wpoly = std::move(wpoly); - r_weld_mesh->wpoly_new = poly_new; + r_weld_mesh->wpoly_new = r_weld_mesh->wpoly.as_mutable_span().drop_front(wpoly_len); r_weld_mesh->wloop_len = wloop_len; r_weld_mesh->wpoly_len = wpoly_len; r_weld_mesh->wpoly_new_len = 0; @@ -833,11 +831,10 @@ static void weld_poly_split_recursive(Span<int> vert_dest_map, if (poly_len < 3 || ctx_verts_len < 1) { return; } - + const int ctx_loops_len = r_wp->loops.len; const int ctx_loops_ofs = r_wp->loops.ofs; MutableSpan<WeldLoop> wloop = r_weld_mesh->wloop; - WeldPoly *wpoly_new = r_weld_mesh->wpoly_new; int loop_kill = 0; @@ -910,7 +907,7 @@ static void weld_poly_split_recursive(Span<int> vert_dest_map, const int new_loops_len = lb - la; const int new_loops_ofs = ctx_loops_ofs + la; - WeldPoly *new_wp = &wpoly_new[r_weld_mesh->wpoly_new_len++]; + WeldPoly *new_wp = &r_weld_mesh->wpoly_new[r_weld_mesh->wpoly_new_len++]; new_wp->poly_dst = OUT_OF_CONTEXT; new_wp->poly_orig = r_wp->poly_orig; new_wp->loops.len = new_loops_len; @@ -973,7 +970,6 @@ static void weld_poly_loop_ctx_setup(Span<MLoop> mloop, { MutableSpan<WeldPoly> wpoly = r_weld_mesh->wpoly; MutableSpan<WeldLoop> wloop = r_weld_mesh->wloop; - WeldPoly *wpoly_new = r_weld_mesh->wpoly_new; int wpoly_len = r_weld_mesh->wpoly_len; int wpoly_new_len = 0; int poly_kill_len = 0; @@ -1036,7 +1032,7 @@ static void weld_poly_loop_ctx_setup(Span<MLoop> mloop, #ifdef USE_WELD_DEBUG weld_assert_poly_and_loop_kill_len(wpoly, - {wpoly_new, wpoly_new_len}, + r_weld_mesh->wpoly_new, wloop, mloop, loop_map, @@ -1172,7 +1168,7 @@ static void weld_poly_loop_ctx_setup(Span<MLoop> mloop, #ifdef USE_WELD_DEBUG weld_assert_poly_and_loop_kill_len(wpoly, - {wpoly_new, wpoly_new_len}, + r_weld_mesh->wpoly_new, wloop, mloop, loop_map, @@ -1182,7 +1178,6 @@ static void weld_poly_loop_ctx_setup(Span<MLoop> mloop, loop_kill_len); #endif - r_weld_mesh->wpoly_new = wpoly_new; r_weld_mesh->poly_kill_len = poly_kill_len; r_weld_mesh->loop_kill_len = loop_kill_len; } |