App: fix possible stack overflow in GroupExtension::hasObject()
This commit is contained in:
@@ -182,34 +182,41 @@ DocumentObject *GroupExtension::getObject(const char *Name) const
|
||||
|
||||
bool GroupExtension::hasObject(const DocumentObject* obj, bool recursive) const
|
||||
{
|
||||
|
||||
if(obj == getExtendedObject())
|
||||
if (obj == getExtendedObject()) {
|
||||
return false;
|
||||
|
||||
const std::vector<DocumentObject*>& grp = Group.getValues();
|
||||
for (auto child : grp) {
|
||||
|
||||
if(!child)
|
||||
continue;
|
||||
|
||||
if (child == obj) {
|
||||
return true;
|
||||
} else if (child == getExtendedObject()) {
|
||||
Base::RuntimeError("Cyclic dependencies detected: Search cannot be performed");
|
||||
} else if ( recursive && child->hasExtension(GroupExtension::getExtensionClassTypeId()) ) {
|
||||
|
||||
App::GroupExtension *subGroup = static_cast<App::GroupExtension *> (
|
||||
child->getExtension(GroupExtension::getExtensionClassTypeId()));
|
||||
std::vector<const GroupExtension*> history;
|
||||
history.push_back(this);
|
||||
|
||||
if (subGroup->recursiveHasObject (obj, subGroup, history)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
try {
|
||||
const std::vector<DocumentObject*>& grp = Group.getValues();
|
||||
for (auto child : grp) {
|
||||
|
||||
if (!child)
|
||||
continue;
|
||||
|
||||
if (child == obj) {
|
||||
return true;
|
||||
}
|
||||
else if (child == getExtendedObject()) {
|
||||
throw Base::RuntimeError("Cyclic dependencies detected: Search cannot be performed");
|
||||
}
|
||||
else if ( recursive && child->hasExtension(GroupExtension::getExtensionClassTypeId()) ) {
|
||||
App::GroupExtension *subGroup = static_cast<App::GroupExtension *> (
|
||||
child->getExtension(GroupExtension::getExtensionClassTypeId()));
|
||||
std::vector<const GroupExtension*> history;
|
||||
history.push_back(this);
|
||||
|
||||
if (subGroup->recursiveHasObject (obj, subGroup, history)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
catch (const Base::RuntimeError& e) {
|
||||
e.ReportException();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool GroupExtension::recursiveHasObject(const DocumentObject* obj, const GroupExtension* group,
|
||||
@@ -235,8 +242,9 @@ bool GroupExtension::recursiveHasObject(const DocumentObject* obj, const GroupEx
|
||||
|
||||
auto ext = child->getExtensionByType<GroupExtension>();
|
||||
|
||||
if(std::find(history.begin(), history.end(), ext) != history.end())
|
||||
Base::RuntimeError("Cyclic dependencies detected: Search cannot be performed");
|
||||
if (std::find(history.begin(), history.end(), ext) != history.end()) {
|
||||
throw Base::RuntimeError("Cyclic dependencies detected: Search cannot be performed");
|
||||
}
|
||||
|
||||
if (recursiveHasObject(obj, ext, history)) {
|
||||
return true;
|
||||
|
||||
@@ -127,8 +127,8 @@ public:
|
||||
|
||||
private:
|
||||
void removeObjectFromDocument(DocumentObject*);
|
||||
//this version if has object stores the already searched objects to prevent infinite recursion
|
||||
//in case of a cyclic group graph
|
||||
// This function stores the already searched objects to prevent infinite recursion in case of a cyclic group graph
|
||||
// It throws an exception of type Base::RuntimeError if a cyclic dependency is detected.
|
||||
bool recursiveHasObject(const DocumentObject* obj, const GroupExtension* group, std::vector<const GroupExtension*> history) const;
|
||||
|
||||
// for tracking children visibility
|
||||
|
||||
Reference in New Issue
Block a user