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
diff options
context:
space:
mode:
authorHans Goudey <h.goudey@me.com>2022-04-16 00:55:15 +0300
committerHans Goudey <h.goudey@me.com>2022-04-16 00:55:15 +0300
commitdc5ae10692520e83277874802e42dac17f6fb95e (patch)
tree7c61a2f85645d865f46b1e35e9b38eb2589aa464
parentcb3c233ed3a5196269f0aa626ea20c7c8aeffebf (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.
-rw-r--r--source/blender/geometry/intern/mesh_merge_by_distance.cc17
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;
}