From a6ef045617da2915a56b7b5bea9b42657f1ee8b1 Mon Sep 17 00:00:00 2001 From: wmayer Date: Wed, 24 Apr 2024 15:14:38 +0200 Subject: [PATCH] Gui: Fix possible crashes with SoDatumLabel There are possible crashes in the methods: * SoDatumLabel::getLabelTextCenter() * SoDatumLabel::generatePrimitives() The two methods expect three points but do not check that they are defined. Depending on the use case of the SoDatumLabel only two points may be defined. Accessing a third point is undefined behaviour. --- src/Gui/SoDatumLabel.cpp | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/src/Gui/SoDatumLabel.cpp b/src/Gui/SoDatumLabel.cpp index 1839e52b24..16713aea0e 100644 --- a/src/Gui/SoDatumLabel.cpp +++ b/src/Gui/SoDatumLabel.cpp @@ -519,10 +519,14 @@ void SoDatumLabel::computeBBox(SoAction * action, SbBox3f &box, SbVec3f ¢er) SbVec3f SoDatumLabel::getLabelTextCenter() { // Get the points stored + int numPts = this->pnts.getNum(); + if (numPts < 2) { + return {}; + } + const SbVec3f* points = this->pnts.getValues(0); SbVec3f p1 = points[0]; SbVec3f p2 = points[1]; - SbVec3f p3 = points[2]; if (datumtype.getValue() == SoDatumLabel::DISTANCE || datumtype.getValue() == SoDatumLabel::DISTANCEX || @@ -538,7 +542,10 @@ SbVec3f SoDatumLabel::getLabelTextCenter() return getLabelTextCenterAngle(p1); } else if (datumtype.getValue() == SoDatumLabel::ARCLENGTH) { - return getLabelTextCenterArcLength(p1, p2, p3); + if (numPts >= 3) { + SbVec3f p3 = points[2]; + return getLabelTextCenterArcLength(p1, p2, p3); + } } return p1; @@ -865,14 +872,19 @@ void SoDatumLabel::generateArcLengthPrimitives(SoAction * action, const SbVec3f& void SoDatumLabel::generatePrimitives(SoAction * action) { // Initialisation check (needs something more sensible) prevents an infinite loop bug - if (this->imgHeight <= FLT_EPSILON || this->imgWidth <= FLT_EPSILON) + if (this->imgHeight <= FLT_EPSILON || this->imgWidth <= FLT_EPSILON) { return; + } + + int numPts = this->pnts.getNum(); + if (numPts < 2) { + return; + } // Get the points stored const SbVec3f *points = this->pnts.getValues(0); SbVec3f p1 = points[0]; SbVec3f p2 = points[1]; - SbVec3f p3 = points[2]; // Change the offset and bounding box parameters depending on Datum Type if (this->datumtype.getValue() == DISTANCE || @@ -896,7 +908,10 @@ void SoDatumLabel::generatePrimitives(SoAction * action) } else if (this->datumtype.getValue() == ARCLENGTH) { - generateArcLengthPrimitives(action, p1, p2, p3); + if (numPts >= 3) { + SbVec3f p3 = points[2]; + generateArcLengthPrimitives(action, p1, p2, p3); + } } }