diff options
| author | Andrey Kleshchev <andreykproductengine@lindenlab.com> | 2022-03-07 22:25:22 +0200 | 
|---|---|---|
| committer | Andrey Kleshchev <andreykproductengine@lindenlab.com> | 2022-03-08 00:51:43 +0200 | 
| commit | 4a4c1388919167f14ef9b48bd2709b07af8b0685 (patch) | |
| tree | c6d81545ab64308f597b77b663eaeaef9aab1717 | |
| parent | fc90fee5087c91bb8c4c93b5e9508706e46bd409 (diff) | |
SL-16984 Fixed inventory loop freezing viewer
| -rw-r--r-- | indra/newview/llinventorymodel.cpp | 22 | 
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; | 
