Fix: Prevent use of uninitialized memory when creating Bezier spline

When Constructing bezier splines from dna, the positions of the
left/right handles were set directly in the internal vectors, by
requesting a reference to them. The problem is that
BezierSpline::handle_positions_left() calls ensure_auto_handles()
before returning the reference. That function does some calculations on
uninitialized memory if the positions array is not yet filled.

Differential Revision: https://developer.blender.org/D13107
This commit is contained in:
Martijn Versteegh 2021-11-11 09:25:10 -06:00 committed by Hans Goudey
parent d26d3cfe19
commit 7aa39b40f4
Notes: blender-bot 2023-02-14 02:30:10 +01:00
Referenced by issue #98965, Regression: Bezier curves fail to respect keyframed handle positions
3 changed files with 25 additions and 8 deletions

View File

@ -306,11 +306,23 @@ class BezierSpline final : public Spline {
blender::Span<HandleType> handle_types_left() const;
blender::MutableSpan<HandleType> handle_types_left();
blender::Span<blender::float3> handle_positions_left() const;
blender::MutableSpan<blender::float3> handle_positions_left();
/**
* Get writable access to the hande position.
*
* \param write_only: pass true for an uninitialized spline, this prevents accessing
* uninitialized memory while autogenerating handles.
*/
blender::MutableSpan<blender::float3> handle_positions_left(bool write_only = false);
blender::Span<HandleType> handle_types_right() const;
blender::MutableSpan<HandleType> handle_types_right();
blender::Span<blender::float3> handle_positions_right() const;
blender::MutableSpan<blender::float3> handle_positions_right();
/**
* Get writable access to the hande position.
*
* \param write_only: pass true for an uninitialized spline, this prevents accessing
* uninitialized memory while autogenerating handles.
*/
blender::MutableSpan<blender::float3> handle_positions_right(bool write_only = false);
void ensure_auto_handles() const;
void translate(const blender::float3 &translation) override;

View File

@ -225,8 +225,8 @@ static SplinePtr spline_from_dna_bezier(const Nurb &nurb)
Span<const BezTriple> src_points{nurb.bezt, nurb.pntsu};
spline->resize(src_points.size());
MutableSpan<float3> positions = spline->positions();
MutableSpan<float3> handle_positions_left = spline->handle_positions_left();
MutableSpan<float3> handle_positions_right = spline->handle_positions_right();
MutableSpan<float3> handle_positions_left = spline->handle_positions_left(true);
MutableSpan<float3> handle_positions_right = spline->handle_positions_right(true);
MutableSpan<BezierSpline::HandleType> handle_types_left = spline->handle_types_left();
MutableSpan<BezierSpline::HandleType> handle_types_right = spline->handle_types_right();
MutableSpan<float> radii = spline->radii();

View File

@ -142,11 +142,14 @@ Span<float3> BezierSpline::handle_positions_left() const
this->ensure_auto_handles();
return handle_positions_left_;
}
MutableSpan<float3> BezierSpline::handle_positions_left()
MutableSpan<float3> BezierSpline::handle_positions_left(const bool write_only)
{
this->ensure_auto_handles();
if (!write_only) {
this->ensure_auto_handles();
}
return handle_positions_left_;
}
Span<BezierSpline::HandleType> BezierSpline::handle_types_right() const
{
return handle_types_right_;
@ -160,9 +163,11 @@ Span<float3> BezierSpline::handle_positions_right() const
this->ensure_auto_handles();
return handle_positions_right_;
}
MutableSpan<float3> BezierSpline::handle_positions_right()
MutableSpan<float3> BezierSpline::handle_positions_right(const bool write_only)
{
this->ensure_auto_handles();
if (!write_only) {
this->ensure_auto_handles();
}
return handle_positions_right_;
}