From dbe504cbd47149e18778c2873486c0e88d629d20 Mon Sep 17 00:00:00 2001
From: Nyx Linden <nyx@lindenlab.com>
Date: Wed, 17 Apr 2013 18:33:39 -0400
Subject: SUN-70 MAINT-2597 FIX Crash when trying to edit no-modify objects

Added protection for invalid / empty inventory contents
---
 indra/newview/llviewerobject.cpp | 36 ++++++++++++++++++++++++------------
 indra/newview/llviewerobject.h   |  2 +-
 2 files changed, 25 insertions(+), 13 deletions(-)

diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index fcf5af76ff..670272e7be 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -2697,24 +2697,33 @@ void LLViewerObject::processTaskInvFile(void** user_data, S32 error_code, LLExtS
 	if(ft && (0 == error_code) &&
 	   (object = gObjectList.findObject(ft->mTaskID)))
 	{
-		object->loadTaskInvFile(ft->mFilename);
+		if (object->loadTaskInvFile(ft->mFilename))
+		{
 
-		LLInventoryObject::object_list_t::iterator it = object->mInventory->begin();
-		LLInventoryObject::object_list_t::iterator end = object->mInventory->end();
-		std::list<LLUUID>& pending_lst = object->mPendingInventoryItemsIDs;
+			LLInventoryObject::object_list_t::iterator it = object->mInventory->begin();
+			LLInventoryObject::object_list_t::iterator end = object->mInventory->end();
+			std::list<LLUUID>& pending_lst = object->mPendingInventoryItemsIDs;
 
-		for (; it != end && pending_lst.size(); ++it)
-		{
-			LLViewerInventoryItem* item = dynamic_cast<LLViewerInventoryItem*>(it->get());
-			if(item && item->getType() != LLAssetType::AT_CATEGORY)
+			for (; it != end && pending_lst.size(); ++it)
 			{
-				std::list<LLUUID>::iterator id_it = std::find(pending_lst.begin(), pending_lst.begin(), item->getAssetUUID());
-				if (id_it != pending_lst.end())
+				LLViewerInventoryItem* item = dynamic_cast<LLViewerInventoryItem*>(it->get());
+				if(item && item->getType() != LLAssetType::AT_CATEGORY)
 				{
-					pending_lst.erase(id_it);
+					std::list<LLUUID>::iterator id_it = std::find(pending_lst.begin(), pending_lst.begin(), item->getAssetUUID());
+					if (id_it != pending_lst.end())
+					{
+						pending_lst.erase(id_it);
+					}
 				}
 			}
 		}
+		else
+		{
+			// MAINT-2597 - crash when trying to edit a no-mod object
+			// Somehow get an contents inventory response, but with an invalid stream (possibly 0 size?)
+			// Stated repro was specific to no-mod objects so failing without user interaction should be safe.
+			llwarns << "Trying to load invalid task inventory file. Ignoring file contents." << llendl;
+		}
 	}
 	else
 	{
@@ -2726,7 +2735,7 @@ void LLViewerObject::processTaskInvFile(void** user_data, S32 error_code, LLExtS
 	delete ft;
 }
 
-void LLViewerObject::loadTaskInvFile(const std::string& filename)
+BOOL LLViewerObject::loadTaskInvFile(const std::string& filename)
 {
 	std::string filename_and_local_path = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, filename);
 	llifstream ifs(filename_and_local_path);
@@ -2773,8 +2782,11 @@ void LLViewerObject::loadTaskInvFile(const std::string& filename)
 	{
 		llwarns << "unable to load task inventory: " << filename_and_local_path
 				<< llendl;
+		return FALSE;
 	}
 	doInventoryCallback();
+
+	return TRUE;
 }
 
 void LLViewerObject::doInventoryCallback()
diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
index 728d279c39..316dbce7d0 100644
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -656,7 +656,7 @@ protected:
 	//
 
 	static void processTaskInvFile(void** user_data, S32 error_code, LLExtStat ext_status);
-	void loadTaskInvFile(const std::string& filename);
+	BOOL loadTaskInvFile(const std::string& filename);
 	void doInventoryCallback();
 	
 	BOOL isOnMap();
-- 
cgit v1.2.3