From 4a4c1388919167f14ef9b48bd2709b07af8b0685 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 7 Mar 2022 22:25:22 +0200 Subject: SL-16984 Fixed inventory loop freezing viewer --- indra/newview/llinventorymodel.cpp | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) (limited to 'indra/newview') 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 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; -- cgit v1.2.3