From 50f732bc019dab23ad3afdcfe6ff920e8972ed72 Mon Sep 17 00:00:00 2001
From: Bradley Payne <vir@lindenlab.com>
Date: Tue, 18 Aug 2009 20:18:40 +0000
Subject: [PATCH] For DEV-34223: Avatar Pipeline Project - M6 (Current Outfit
 Folder).  Make sure that only wearables from the COF are handled as wearables
 during initial COF load. Added error checking for null asset IDs. This fixes
 a crash on login observed after loading from COF was enabled.

---
 indra/newview/llagentwearables.cpp  | 52 ++++++++++++++++++++---------
 indra/newview/llinventorybridge.cpp |  9 -----
 indra/newview/llinventorymodel.h    | 14 ++++++++
 3 files changed, 50 insertions(+), 25 deletions(-)

diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp
index 1b496d44cd6..0f735282cb0 100644
--- a/indra/newview/llagentwearables.cpp
+++ b/indra/newview/llagentwearables.cpp
@@ -1816,10 +1816,13 @@ void LLInitialWearablesFetch::done()
 	// and set up an observer that will wait for that to happen.
 	LLInventoryModel::cat_array_t cat_array;
 	LLInventoryModel::item_array_t item_array;
-	gInventory.collectDescendents(mCompleteFolders.front(),
-								  cat_array,
-								  item_array,
-								  LLInventoryModel::EXCLUDE_TRASH);
+
+	LLFindWearables is_wearable;
+	gInventory.collectDescendentsIf(mCompleteFolders.front(),
+									cat_array,
+									item_array,
+									LLInventoryModel::EXCLUDE_TRASH,
+									is_wearable);
 	S32 count = item_array.count();
 	mCOFInitialWearables.reserve(count);
 	
@@ -1856,10 +1859,18 @@ void LLInitialWearablesFetch::processInitialWearables()
 		{
 			// Fetch the wearables in the current outfit folder
 			InitialWearableData *wearable_data = new InitialWearableData(mCOFInitialWearables[i]); // This will be deleted in the callback.
-			LLWearableList::instance().getAsset(wearable_data->mAssetID,
-												LLStringUtil::null,
-												LLWearableDictionary::getAssetType(wearable_data->mType),
-												LLAgentWearables::onInitialWearableAssetArrived, (void*)(wearable_data));			
+			if (wearable_data->mAssetID.notNull())
+			{
+				LLWearableList::instance().getAsset(wearable_data->mAssetID,
+													LLStringUtil::null,
+													LLWearableDictionary::getAssetType(wearable_data->mType),
+													LLAgentWearables::onInitialWearableAssetArrived, (void*)(wearable_data));			
+			}
+			else
+			{
+				llinfos << "Invalid wearable, type " << wearable_data->mType << " itemID "
+						<< wearable_data->mItemID << " assetID " << wearable_data->mAssetID << llendl;
+			}
 		}
 	}
 	else 
@@ -1871,16 +1882,25 @@ void LLInitialWearablesFetch::processInitialWearables()
 		{
 			// Populate the current outfit folder with links to the wearables passed in the message
 			InitialWearableData *wearable_data = new InitialWearableData(mAgentInitialWearables[i]); // This will be deleted in the callback.
+
+			if (wearable_data->mAssetID.notNull())
+			{
 #ifdef USE_CURRENT_OUTFIT_FOLDER
-			const std::string link_name = "WearableLink"; // Unimportant what this is named, it isn't exposed.
-			link_inventory_item(gAgent.getID(), wearable_data->mItemID, current_outfit_id, link_name,
-								LLAssetType::AT_LINK, LLPointer<LLInventoryCallback>(NULL));
+				const std::string link_name = "WearableLink"; // Unimportant what this is named, it isn't exposed.
+				link_inventory_item(gAgent.getID(), wearable_data->mItemID, current_outfit_id, link_name,
+									LLAssetType::AT_LINK, LLPointer<LLInventoryCallback>(NULL));
 #endif
-			// Fetch the wearables
-			LLWearableList::instance().getAsset(wearable_data->mAssetID,
-												LLStringUtil::null,
-												LLWearableDictionary::getAssetType(wearable_data->mType),
-												LLAgentWearables::onInitialWearableAssetArrived, (void*)(wearable_data));
+				// Fetch the wearables
+				LLWearableList::instance().getAsset(wearable_data->mAssetID,
+													LLStringUtil::null,
+													LLWearableDictionary::getAssetType(wearable_data->mType),
+													LLAgentWearables::onInitialWearableAssetArrived, (void*)(wearable_data));
+			}
+			else
+			{
+				llinfos << "Invalid wearable, type " << wearable_data->mType << " itemID "
+						<< wearable_data->mItemID << " assetID " << wearable_data->mAssetID << llendl;
+			}
 		}
 	}
 	else
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 45003fe56c9..54802ee7620 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -1658,15 +1658,6 @@ BOOL move_inv_category_world_to_agent(const LLUUID& object_id,
 	return accept;
 }
 
-class LLFindWearables : public LLInventoryCollectFunctor
-{
-public:
-	LLFindWearables() {}
-	virtual ~LLFindWearables() {}
-	virtual bool operator()(LLInventoryCategory* cat,
-							LLInventoryItem* item);
-};
-
 bool LLFindWearables::operator()(LLInventoryCategory* cat,
 								 LLInventoryItem* item)
 {
diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h
index e38447a8f27..2ddc35b9ef3 100644
--- a/indra/newview/llinventorymodel.h
+++ b/indra/newview/llinventorymodel.h
@@ -726,6 +726,20 @@ class LLNameCategoryCollector : public LLInventoryCollectFunctor
 	std::string mName;
 };
 
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Class LLFindWearables
+//
+// Collects wearables based on item type.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+class LLFindWearables : public LLInventoryCollectFunctor
+{
+public:
+	LLFindWearables() {}
+	virtual ~LLFindWearables() {}
+	virtual bool operator()(LLInventoryCategory* cat,
+							LLInventoryItem* item);
+};
+
 
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 // Class LLInventoryCompletionObserver
-- 
GitLab