Skip to content

Commit

Permalink
+ fixes #1720: Freecad crash when handling invalid sketches
Browse files Browse the repository at this point in the history
  • Loading branch information
wwmayer committed Dec 28, 2014
1 parent 6a211b9 commit 7d8b1f3
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 31 deletions.
74 changes: 43 additions & 31 deletions src/Mod/Sketcher/App/SketchObject.cpp
Expand Up @@ -2160,6 +2160,47 @@ void SketchObject::appendRedundantMsg(const std::vector<int> &redundant, std::st
msg = ss.str();
}

bool SketchObject::evaluateConstraint(const Constraint *constraint) const
{
int intGeoCount = getHighestCurveIndex() + 1;
int extGeoCount = getExternalGeometryCount();

switch (constraint->Type) {
case Horizontal:
case Vertical:
case Radius:
case Distance:
case DistanceX:
case DistanceY:
if (constraint->First < -extGeoCount || constraint->First >= intGeoCount)
return false;
break;
case Coincident:
case Perpendicular:
case Parallel:
case Equal:
case PointOnObject:
case Tangent:
case Symmetric:
if (constraint->First < -extGeoCount || constraint->First >= intGeoCount)
return false;
if (constraint->Second < -extGeoCount || constraint->Second >= intGeoCount)
return false;
break;
case Angle:
if (constraint->First < -extGeoCount || constraint->First >= intGeoCount)
return false;
if ((constraint->Second < -extGeoCount || constraint->Second >= intGeoCount) &&
constraint->Second != Constraint::GeoUndef)
return false;
break;
default:
break;
}

return true;
}

bool SketchObject::evaluateConstraints() const
{
int intGeoCount = getHighestCurveIndex() + 1;
Expand All @@ -2174,37 +2215,8 @@ bool SketchObject::evaluateConstraints() const

std::vector<Sketcher::Constraint *>::const_iterator it;
for (it = constraints.begin(); it != constraints.end(); ++it) {
switch ((*it)->Type) {
case Horizontal:
case Vertical:
case Radius:
case Distance:
case DistanceX:
case DistanceY:
if ((*it)->First < -extGeoCount || (*it)->First >= intGeoCount)
return false;
break;
case Perpendicular:
case Parallel:
case Equal:
case PointOnObject:
case Tangent:
case Symmetric:
if ((*it)->First < -extGeoCount || (*it)->First >= intGeoCount)
return false;
if ((*it)->Second < -extGeoCount || (*it)->Second >= intGeoCount)
return false;
break;
case Angle:
if ((*it)->First < -extGeoCount || (*it)->First >= intGeoCount)
return false;
if (((*it)->Second < -extGeoCount || (*it)->Second >= intGeoCount) &&
(*it)->Second != Constraint::GeoUndef)
return false;
break;
default:
break;
}
if (!evaluateConstraint(*it))
return false;
}

return true;
Expand Down
2 changes: 2 additions & 0 deletions src/Mod/Sketcher/App/SketchObject.h
Expand Up @@ -164,6 +164,8 @@ class SketcherExport SketchObject : public Part::Part2DObject
virtual Base::Axis getAxis(int axId) const;
/// verify and accept the assigned geometry
virtual void acceptGeometry();
/// Check if constraint has invalid indexes
bool evaluateConstraint(const Constraint *constraint) const;
/// Check for constraints with invalid indexes
bool evaluateConstraints() const;
/// Remove constraints with invalid indexes
Expand Down
10 changes: 10 additions & 0 deletions src/Mod/Sketcher/App/SketchObjectPyImp.cpp
Expand Up @@ -236,6 +236,10 @@ PyObject* SketchObjectPy::addConstraint(PyObject *args)

if (PyObject_TypeCheck(pcObj, &(Sketcher::ConstraintPy::Type))) {
Sketcher::Constraint *constr = static_cast<Sketcher::ConstraintPy*>(pcObj)->getConstraintPtr();
if (!this->getSketchObjectPtr()->evaluateConstraint(constr)) {
PyErr_SetString(PyExc_IndexError, "Constraint has invalid indexes");
return 0;
}
int ret = this->getSketchObjectPtr()->addConstraint(constr);
this->getSketchObjectPtr()->solve();
return Py::new_reference_to(Py::Int(ret));
Expand All @@ -251,6 +255,12 @@ PyObject* SketchObjectPy::addConstraint(PyObject *args)
}
}

for (std::vector<Constraint*>::iterator it = values.begin(); it != values.end(); ++it) {
if (!this->getSketchObjectPtr()->evaluateConstraint(*it)) {
PyErr_SetString(PyExc_IndexError, "Constraint has invalid indexes");
return 0;
}
}
int ret = getSketchObjectPtr()->addConstraints(values) + 1;
std::size_t numCon = values.size();
Py::Tuple tuple(numCon);
Expand Down

0 comments on commit 7d8b1f3

Please sign in to comment.