summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrey Kleshchev <andreykproductengine@lindenlab.com>2022-03-07 22:25:22 +0200
committerAndrey Kleshchev <andreykproductengine@lindenlab.com>2022-03-08 00:51:43 +0200
commit4a4c1388919167f14ef9b48bd2709b07af8b0685 (patch)
treec6d81545ab64308f597b77b663eaeaef9aab1717
parentfc90fee5087c91bb8c4c93b5e9508706e46bd409 (diff)
SL-16984 Fixed inventory loop freezing viewer
-rw-r--r--indra/newview/llinventorymodel.cpp22
1 files changed, 18 insertions, 4 deletions
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index 29fbcc968f..ea22750c1f 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -340,12 +340,26 @@ const LLViewerInventoryCategory* LLInventoryModel::getFirstDescendantOf(const LL
bool LLInventoryModel::getObjectTopmostAncestor(const LLUUID& object_id, LLUUID& result) const
{
LLInventoryObject *object = getObject(object_id);
- while (object && object->getParentUUID().notNull())
- {
- LLInventoryObject *parent_object = getObject(object->getParentUUID());
+ if (!object)
+ {
+ LL_WARNS(LOG_INV) << "Unable to trace topmost ancestor, initial object " << object_id << " does not exist" << LL_ENDL;
+ return false;
+ }
+
+ std::set<LLUUID> object_ids{ object_id }; // loop protection
+ while (object->getParentUUID().notNull())
+ {
+ LLUUID parent_id = object->getParentUUID();
+ if (object_ids.find(parent_id) != object_ids.end())
+ {
+ LL_WARNS(LOG_INV) << "Detected a loop on an object " << parent_id << " when searching for ancestor of " << object_id << LL_ENDL;
+ return false;
+ }
+ object_ids.insert(parent_id);
+ LLInventoryObject *parent_object = getObject(parent_id);
if (!parent_object)
{
- LL_WARNS(LOG_INV) << "unable to trace topmost ancestor, missing item for uuid " << object->getParentUUID() << LL_ENDL;
+ LL_WARNS(LOG_INV) << "unable to trace topmost ancestor of " << object_id << ", missing item for uuid " << parent_id << LL_ENDL;
return false;
}
object = parent_object;