Sketcher: Fix use after free Bug when commiting value with enter in OVP (#23853)

* Sketcher: Fix use after free Bug when commiting value with enter

* Fix new use after free bug

---------

Co-authored-by: Matthias Danner <28687794+matthiasdanner@users.noreply.github.com>
This commit is contained in:
matthiasdanner
2025-09-12 16:18:09 +02:00
committed by GitHub
parent a5dc10f924
commit 347eaacada
17 changed files with 95 additions and 69 deletions

View File

@@ -419,7 +419,7 @@ public:
// -> A machine does not forward to a next state when adapting the parameter (though it
// may forward to
// a next state if all the parameters are fulfilled, see
// doChangeDrawSketchHandlerMode). This ensures that the geometry has been defined
// computeNextDrawSketchHandlerMode). This ensures that the geometry has been defined
// (either by mouse clicking or by widget). Autoconstraints on point should be picked
// when the state is reached upon machine state advancement.
//
@@ -476,7 +476,7 @@ public:
/** Change DSH to reflect the SelectMode it should be in based on values entered in the
* controls
*/
virtual void doChangeDrawSketchHandlerMode()
virtual void computeNextDrawSketchHandlerMode()
{}
/** function that is called by the handler when the selection mode changed */
@@ -628,11 +628,17 @@ protected:
// preselectAtPoint.
handler->updateDataAndDrawToPosition(lastControlEnforcedPosition);
doChangeDrawSketchHandlerMode();
computeNextDrawSketchHandlerMode();
auto nextState = handler->getNextState();
bool shouldProcessLastPosWithNextState =
nextState && nextState != SelectMode::End && nextState != currentstate && firstMoveInit;
// the handler will be destroyed in applyNextState if the nextState is End
handler->applyNextState();
// if the state changed and is not the last state (End). And is init (ie tool has not
// reset)
if (!handler->isLastState() && handler->state() != currentstate && firstMoveInit) {
if (shouldProcessLastPosWithNextState) {
// mode has changed, so reprocess the previous position to the new widget state
handler->mouseMove(prevCursorPosition);
}

View File

@@ -177,6 +177,25 @@ protected:
return Mode == state;
}
void setNextState(std::optional<SelectModeT> nextState)
{
nextMode = nextState;
}
std::optional<SelectModeT> getNextState()
{
return nextMode;
}
void applyNextState()
{
if (nextMode) {
auto next = std::move(*nextMode);
nextMode = std::nullopt;
setState(next);
}
}
bool isFirstState() const
{
return Mode == (static_cast<SelectModeT>(0));
@@ -192,11 +211,10 @@ protected:
return static_cast<SelectModeT>(0);
}
SelectModeT getNextMode() const
SelectModeT computeNextMode() const
{
auto modeint = static_cast<int>(state());
if (modeint < maxMode) {
auto newmode = static_cast<SelectModeT>(modeint + 1);
return newmode;
@@ -208,11 +226,12 @@ protected:
void moveToNextMode()
{
setState(getNextMode());
setState(computeNextMode());
}
void reset()
{
nextMode = std::nullopt;
if (Mode != static_cast<SelectModeT>(0)) {
setState(static_cast<SelectModeT>(0));
}
@@ -225,6 +244,7 @@ protected:
private:
SelectModeT Mode;
std::optional<SelectModeT> nextMode;
static const constexpr int maxMode = static_cast<int>(SelectModeT::End);
};

View File

@@ -225,7 +225,7 @@ public:
{}
/** function that is called by the handler with a Vector2d position to update the widget*/
void doChangeDrawSketchHandlerMode() override
void computeNextDrawSketchHandlerMode() override
{}
/** function that is called by the handler with a Vector2d position to update the widget */

View File

@@ -749,7 +749,7 @@ void DSHArcController::adaptParameters(Base::Vector2d onSketchPos)
}
template<>
void DSHArcController::doChangeDrawSketchHandlerMode()
void DSHArcController::computeNextDrawSketchHandlerMode()
{
switch (handler->state()) {
case SelectMode::SeekFirst: {
@@ -757,7 +757,7 @@ void DSHArcController::doChangeDrawSketchHandlerMode()
auto& secondParam = onViewParameters[OnViewParameter::Second];
if (firstParam->hasFinishedEditing && secondParam->hasFinishedEditing) {
handler->setState(SelectMode::SeekSecond);
handler->setNextState(SelectMode::SeekSecond);
}
} break;
case SelectMode::SeekSecond: {
@@ -765,21 +765,21 @@ void DSHArcController::doChangeDrawSketchHandlerMode()
auto& fourthParam = onViewParameters[OnViewParameter::Fourth];
if (thirdParam->hasFinishedEditing && fourthParam->hasFinishedEditing) {
handler->setState(SelectMode::SeekThird);
handler->setNextState(SelectMode::SeekThird);
}
} break;
case SelectMode::SeekThird: {
auto& fifthParam = onViewParameters[OnViewParameter::Fifth];
if (handler->constructionMethod() == DrawSketchHandlerArc::ConstructionMethod::Center) {
if (fifthParam->hasFinishedEditing) {
handler->setState(SelectMode::End);
handler->setNextState(SelectMode::End);
}
}
else {
auto& sixthParam = onViewParameters[OnViewParameter::Sixth];
if (fifthParam->hasFinishedEditing && sixthParam->hasFinishedEditing) {
handler->setState(SelectMode::End);
handler->setNextState(SelectMode::End);
}
}
} break;

View File

@@ -797,7 +797,7 @@ void DSHArcSlotController::adaptParameters(Base::Vector2d onSketchPos)
}
template<>
void DSHArcSlotController::doChangeDrawSketchHandlerMode()
void DSHArcSlotController::computeNextDrawSketchHandlerMode()
{
switch (handler->state()) {
case SelectMode::SeekFirst: {
@@ -805,7 +805,7 @@ void DSHArcSlotController::doChangeDrawSketchHandlerMode()
auto& secondParam = onViewParameters[OnViewParameter::Second];
if (firstParam->hasFinishedEditing && secondParam->hasFinishedEditing) {
handler->setState(SelectMode::SeekSecond);
handler->setNextState(SelectMode::SeekSecond);
}
} break;
case SelectMode::SeekSecond: {
@@ -813,21 +813,21 @@ void DSHArcSlotController::doChangeDrawSketchHandlerMode()
auto& fourthParam = onViewParameters[OnViewParameter::Fourth];
if (thirdParam->hasFinishedEditing && fourthParam->hasFinishedEditing) {
handler->setState(SelectMode::SeekThird);
handler->setNextState(SelectMode::SeekThird);
}
} break;
case SelectMode::SeekThird: {
auto& fifthParam = onViewParameters[OnViewParameter::Fifth];
if (fifthParam->hasFinishedEditing) {
handler->setState(SelectMode::SeekFourth);
handler->setNextState(SelectMode::SeekFourth);
}
} break;
case SelectMode::SeekFourth: {
auto& sixthParam = onViewParameters[OnViewParameter::Sixth];
if (sixthParam->hasFinishedEditing) {
handler->setState(SelectMode::End);
handler->setNextState(SelectMode::End);
}
} break;
default:

View File

@@ -1108,7 +1108,7 @@ void DSHBSplineController::adaptParameters(Base::Vector2d onSketchPos)
}
template<>
void DSHBSplineController::doChangeDrawSketchHandlerMode()
void DSHBSplineController::computeNextDrawSketchHandlerMode()
{
switch (handler->state()) {
case SelectMode::SeekFirst: {

View File

@@ -624,7 +624,7 @@ void DSHCircleController::adaptParameters(Base::Vector2d onSketchPos)
}
template<>
void DSHCircleController::doChangeDrawSketchHandlerMode()
void DSHCircleController::computeNextDrawSketchHandlerMode()
{
switch (handler->state()) {
case SelectMode::SeekFirst: {
@@ -632,7 +632,7 @@ void DSHCircleController::doChangeDrawSketchHandlerMode()
auto& secondParam = onViewParameters[OnViewParameter::Second];
if (firstParam->hasFinishedEditing && secondParam->hasFinishedEditing) {
handler->setState(SelectMode::SeekSecond);
handler->setNextState(SelectMode::SeekSecond);
}
} break;
case SelectMode::SeekSecond: {
@@ -642,7 +642,7 @@ void DSHCircleController::doChangeDrawSketchHandlerMode()
&& handler->constructionMethod()
== DrawSketchHandlerCircle::ConstructionMethod::Center) {
handler->setState(SelectMode::End);
handler->setNextState(SelectMode::End);
}
else if (onViewParameters.size() > 3) {
auto& fourthParam = onViewParameters[OnViewParameter::Fourth];
@@ -650,7 +650,7 @@ void DSHCircleController::doChangeDrawSketchHandlerMode()
&& handler->constructionMethod()
== DrawSketchHandlerCircle::ConstructionMethod::ThreeRim) {
handler->setState(SelectMode::SeekThird);
handler->setNextState(SelectMode::SeekThird);
}
}
} break;
@@ -659,7 +659,7 @@ void DSHCircleController::doChangeDrawSketchHandlerMode()
auto& sixthParam = onViewParameters[OnViewParameter::Sixth];
if (fifthParam->hasFinishedEditing && sixthParam->hasFinishedEditing) {
handler->setState(SelectMode::End);
handler->setNextState(SelectMode::End);
}
} break;
default:

View File

@@ -724,7 +724,7 @@ void DSHEllipseController::adaptParameters(Base::Vector2d onSketchPos)
}
template<>
void DSHEllipseController::doChangeDrawSketchHandlerMode()
void DSHEllipseController::computeNextDrawSketchHandlerMode()
{
switch (handler->state()) {
case SelectMode::SeekFirst: {
@@ -732,7 +732,7 @@ void DSHEllipseController::doChangeDrawSketchHandlerMode()
auto& secondParam = onViewParameters[OnViewParameter::Second];
if (firstParam->hasFinishedEditing && secondParam->hasFinishedEditing) {
handler->setState(SelectMode::SeekSecond);
handler->setNextState(SelectMode::SeekSecond);
}
} break;
case SelectMode::SeekSecond: {
@@ -740,7 +740,7 @@ void DSHEllipseController::doChangeDrawSketchHandlerMode()
auto& fourthParam = onViewParameters[OnViewParameter::Fourth];
if (thirdParam->hasFinishedEditing && fourthParam->hasFinishedEditing) {
handler->setState(SelectMode::SeekThird);
handler->setNextState(SelectMode::SeekThird);
}
} break;
case SelectMode::SeekThird: {
@@ -749,13 +749,13 @@ void DSHEllipseController::doChangeDrawSketchHandlerMode()
if (handler->constructionMethod()
== DrawSketchHandlerEllipse::ConstructionMethod::Center) {
if (fifthParam->hasFinishedEditing) {
handler->setState(SelectMode::End);
handler->setNextState(SelectMode::End);
}
}
else {
auto& sixthParam = onViewParameters[OnViewParameter::Sixth];
if (fifthParam->hasFinishedEditing && sixthParam->hasFinishedEditing) {
handler->setState(SelectMode::End);
handler->setNextState(SelectMode::End);
}
}
} break;

View File

@@ -592,7 +592,7 @@ void DSHLineController::adaptParameters(Base::Vector2d onSketchPos)
}
template<>
void DSHLineController::doChangeDrawSketchHandlerMode()
void DSHLineController::computeNextDrawSketchHandlerMode()
{
switch (handler->state()) {
case SelectMode::SeekFirst: {
@@ -600,7 +600,7 @@ void DSHLineController::doChangeDrawSketchHandlerMode()
auto& secondParam = onViewParameters[OnViewParameter::Second];
if (firstParam->hasFinishedEditing && secondParam->hasFinishedEditing) {
handler->setState(SelectMode::SeekSecond);
handler->setNextState(SelectMode::SeekSecond);
}
} break;
case SelectMode::SeekSecond: {
@@ -608,7 +608,7 @@ void DSHLineController::doChangeDrawSketchHandlerMode()
auto& fourthParam = onViewParameters[OnViewParameter::Fourth];
if (thirdParam->hasFinishedEditing && fourthParam->hasFinishedEditing) {
handler->setState(SelectMode::End);
handler->setNextState(SelectMode::End);
}
} break;
default:

View File

@@ -1206,14 +1206,14 @@ void DSHOffsetController::adaptParameters(Base::Vector2d onSketchPos)
}
template<>
void DSHOffsetController::doChangeDrawSketchHandlerMode()
void DSHOffsetController::computeNextDrawSketchHandlerMode()
{
switch (handler->state()) {
case SelectMode::SeekFirst: {
auto& firstParam = onViewParameters[OnViewParameter::First];
if (firstParam->hasFinishedEditing) {
handler->setState(SelectMode::End);
handler->setNextState(SelectMode::End);
}
} break;
default:

View File

@@ -229,7 +229,7 @@ void DSHPointController::adaptParameters(Base::Vector2d onSketchPos)
}
template<>
void DSHPointController::doChangeDrawSketchHandlerMode()
void DSHPointController::computeNextDrawSketchHandlerMode()
{
switch (handler->state()) {
case SelectMode::SeekFirst: {
@@ -237,7 +237,7 @@ void DSHPointController::doChangeDrawSketchHandlerMode()
auto& secondParam = onViewParameters[OnViewParameter::Second];
if (firstParam->hasFinishedEditing && secondParam->hasFinishedEditing) {
handler->setState(SelectMode::End);
handler->setNextState(SelectMode::End);
// handler->finish(); // Called by the change of mode
}
} break;

View File

@@ -454,7 +454,7 @@ void DSHPolygonController::adaptParameters(Base::Vector2d onSketchPos)
}
template<>
void DSHPolygonController::doChangeDrawSketchHandlerMode()
void DSHPolygonController::computeNextDrawSketchHandlerMode()
{
switch (handler->state()) {
case SelectMode::SeekFirst: {
@@ -462,7 +462,7 @@ void DSHPolygonController::doChangeDrawSketchHandlerMode()
auto& secondParam = onViewParameters[OnViewParameter::Second];
if (firstParam->hasFinishedEditing && secondParam->hasFinishedEditing) {
handler->setState(SelectMode::SeekSecond);
handler->setNextState(SelectMode::SeekSecond);
}
} break;
case SelectMode::SeekSecond: {
@@ -470,7 +470,7 @@ void DSHPolygonController::doChangeDrawSketchHandlerMode()
auto& fourthParam = onViewParameters[OnViewParameter::Fourth];
if (thirdParam->hasFinishedEditing && fourthParam->hasFinishedEditing) {
handler->setState(SelectMode::End);
handler->setNextState(SelectMode::End);
}
} break;
default:

View File

@@ -2474,14 +2474,14 @@ void DSHRectangleController::adaptParameters(Base::Vector2d onSketchPos)
}
template<>
void DSHRectangleController::doChangeDrawSketchHandlerMode()
void DSHRectangleController::computeNextDrawSketchHandlerMode()
{
switch (handler->state()) {
case SelectMode::SeekFirst: {
if (onViewParameters[OnViewParameter::First]->hasFinishedEditing
&& onViewParameters[OnViewParameter::Second]->hasFinishedEditing) {
handler->setState(SelectMode::SeekSecond);
handler->setNextState(SelectMode::SeekSecond);
}
} break;
case SelectMode::SeekSecond: {
@@ -2492,10 +2492,10 @@ void DSHRectangleController::doChangeDrawSketchHandlerMode()
|| handler->constructionMethod() == ConstructionMethod::ThreePoints
|| handler->constructionMethod() == ConstructionMethod::CenterAnd3Points) {
handler->setState(SelectMode::SeekThird);
handler->setNextState(SelectMode::SeekThird);
}
else {
handler->setState(SelectMode::End);
handler->setNextState(SelectMode::End);
}
}
} break;
@@ -2506,26 +2506,26 @@ void DSHRectangleController::doChangeDrawSketchHandlerMode()
&& onViewParameters[OnViewParameter::Fifth]->hasFinishedEditing) {
if (handler->makeFrame) {
handler->setState(SelectMode::SeekFourth);
handler->setNextState(SelectMode::SeekFourth);
}
else {
handler->setState(SelectMode::End);
handler->setNextState(SelectMode::End);
}
}
else if (handler->makeFrame
&& onViewParameters[OnViewParameter::Sixth]->hasFinishedEditing) {
handler->setState(SelectMode::End);
handler->setNextState(SelectMode::End);
}
}
else {
if (onViewParameters[OnViewParameter::Fifth]->hasFinishedEditing
&& onViewParameters[OnViewParameter::Sixth]->hasFinishedEditing) {
if (handler->roundCorners || handler->makeFrame) {
handler->setState(SelectMode::SeekFourth);
handler->setNextState(SelectMode::SeekFourth);
}
else {
handler->setState(SelectMode::End);
handler->setNextState(SelectMode::End);
}
}
}
@@ -2534,7 +2534,7 @@ void DSHRectangleController::doChangeDrawSketchHandlerMode()
if (handler->constructionMethod() == ConstructionMethod::Diagonal
|| handler->constructionMethod() == ConstructionMethod::CenterAndCorner) {
if (onViewParameters[OnViewParameter::Sixth]->hasFinishedEditing) {
handler->setState(SelectMode::End);
handler->setNextState(SelectMode::End);
}
}
else {
@@ -2542,22 +2542,22 @@ void DSHRectangleController::doChangeDrawSketchHandlerMode()
&& onViewParameters[OnViewParameter::Seventh]->hasFinishedEditing) {
if (handler->makeFrame) {
handler->setState(SelectMode::SeekFifth);
handler->setNextState(SelectMode::SeekFifth);
}
else {
handler->setState(SelectMode::End);
handler->setNextState(SelectMode::End);
}
}
else if (handler->makeFrame
&& onViewParameters[OnViewParameter::Eighth]->hasFinishedEditing) {
handler->setState(SelectMode::End);
handler->setNextState(SelectMode::End);
}
}
} break;
case SelectMode::SeekFifth: {
if (handler->makeFrame
&& onViewParameters[OnViewParameter::Eighth]->hasFinishedEditing) {
handler->setState(SelectMode::End);
handler->setNextState(SelectMode::End);
}
} break;
default:

View File

@@ -692,7 +692,7 @@ void DSHRotateController::adaptParameters(Base::Vector2d onSketchPos)
}
template<>
void DSHRotateController::doChangeDrawSketchHandlerMode()
void DSHRotateController::computeNextDrawSketchHandlerMode()
{
switch (handler->state()) {
case SelectMode::SeekFirst: {
@@ -700,7 +700,7 @@ void DSHRotateController::doChangeDrawSketchHandlerMode()
auto& secondParam = onViewParameters[OnViewParameter::Second];
if (firstParam->hasFinishedEditing && secondParam->hasFinishedEditing) {
handler->setState(SelectMode::SeekSecond);
handler->setNextState(SelectMode::SeekSecond);
}
} break;
case SelectMode::SeekSecond: {
@@ -708,14 +708,14 @@ void DSHRotateController::doChangeDrawSketchHandlerMode()
if (thirdParam->hasFinishedEditing) {
handler->totalAngle = Base::toRadians(thirdParam->getValue());
handler->setState(SelectMode::End);
handler->setNextState(SelectMode::End);
}
} break;
case SelectMode::SeekThird: {
auto& fourthParam = onViewParameters[OnViewParameter::Fourth];
if (fourthParam->hasFinishedEditing) {
handler->setState(SelectMode::End);
handler->setNextState(SelectMode::End);
}
} break;
default:

View File

@@ -669,20 +669,20 @@ void DSHScaleController::adaptParameters(Base::Vector2d onSketchPos)
}
template<>
void DSHScaleController::doChangeDrawSketchHandlerMode()
void DSHScaleController::computeNextDrawSketchHandlerMode()
{
switch (handler->state()) {
case SelectMode::SeekFirst: {
if (onViewParameters[OnViewParameter::First]->isSet
&& onViewParameters[OnViewParameter::Second]->isSet) {
handler->setState(SelectMode::SeekSecond);
handler->setNextState(SelectMode::SeekSecond);
}
} break;
case SelectMode::SeekThird: {
if (onViewParameters[OnViewParameter::Third]->hasFinishedEditing) {
handler->setState(SelectMode::End);
handler->setNextState(SelectMode::End);
}
} break;
break;

View File

@@ -544,7 +544,7 @@ void DSHSlotController::adaptParameters(Base::Vector2d onSketchPos)
}
template<>
void DSHSlotController::doChangeDrawSketchHandlerMode()
void DSHSlotController::computeNextDrawSketchHandlerMode()
{
switch (handler->state()) {
case SelectMode::SeekFirst: {
@@ -552,7 +552,7 @@ void DSHSlotController::doChangeDrawSketchHandlerMode()
auto& secondParam = onViewParameters[OnViewParameter::Second];
if (firstParam->hasFinishedEditing && secondParam->hasFinishedEditing) {
handler->setState(SelectMode::SeekSecond);
handler->setNextState(SelectMode::SeekSecond);
}
} break;
case SelectMode::SeekSecond: {
@@ -560,14 +560,14 @@ void DSHSlotController::doChangeDrawSketchHandlerMode()
auto& fourthParam = onViewParameters[OnViewParameter::Fourth];
if (thirdParam->hasFinishedEditing && fourthParam->hasFinishedEditing) {
handler->setState(SelectMode::SeekThird);
handler->setNextState(SelectMode::SeekThird);
}
} break;
case SelectMode::SeekThird: {
auto& fifthParam = onViewParameters[OnViewParameter::Fifth];
if (fifthParam->hasFinishedEditing) {
handler->setState(SelectMode::End);
handler->setNextState(SelectMode::End);
}
} break;
default:

View File

@@ -736,7 +736,7 @@ void DSHTranslateController::adaptParameters(Base::Vector2d onSketchPos)
}
template<>
void DSHTranslateController::doChangeDrawSketchHandlerMode()
void DSHTranslateController::computeNextDrawSketchHandlerMode()
{
switch (handler->state()) {
case SelectMode::SeekFirst: {
@@ -744,7 +744,7 @@ void DSHTranslateController::doChangeDrawSketchHandlerMode()
auto& secondParam = onViewParameters[OnViewParameter::Second];
if (firstParam->hasFinishedEditing && secondParam->hasFinishedEditing) {
handler->setState(SelectMode::SeekSecond);
handler->setNextState(SelectMode::SeekSecond);
}
} break;
case SelectMode::SeekSecond: {
@@ -753,10 +753,10 @@ void DSHTranslateController::doChangeDrawSketchHandlerMode()
if (thirdParam->hasFinishedEditing && fourthParam->hasFinishedEditing) {
if (handler->secondNumberOfCopies == 1) {
handler->setState(SelectMode::End);
handler->setNextState(SelectMode::End);
}
else {
handler->setState(SelectMode::SeekThird);
handler->setNextState(SelectMode::SeekThird);
}
}
} break;
@@ -765,7 +765,7 @@ void DSHTranslateController::doChangeDrawSketchHandlerMode()
auto& sixthParam = onViewParameters[OnViewParameter::Sixth];
if (fifthParam->hasFinishedEditing && sixthParam->hasFinishedEditing) {
handler->setState(SelectMode::End);
handler->setNextState(SelectMode::End);
}
} break;
default: