App: fix possible stack overflow in GroupExtension::hasObject()

This commit is contained in:
wmayer
2022-11-17 00:30:44 +01:00
parent 955eeb4775
commit d793a182c4
2 changed files with 37 additions and 29 deletions

View File

@@ -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;

View File

@@ -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