diff --git a/indra/llcommon/llsdserialize.cpp b/indra/llcommon/llsdserialize.cpp
index ede212181d96e2ada8d01a65c4155a2841534f46..be54ed053bee7d6d3d918260251b3ccfaee14810 100644
--- a/indra/llcommon/llsdserialize.cpp
+++ b/indra/llcommon/llsdserialize.cpp
@@ -2121,22 +2121,13 @@ std::string zip_llsd(LLSD& data)
 	deflateEnd(&strm);
 	free(output);
 
-#if 0 //verify results work with unzip_llsd
-	std::istringstream test(result);
-	LLSD test_sd;
-	if (!unzip_llsd(test_sd, test, result.size()))
-	{
-		LL_ERRS() << "Invalid compression result!" << LL_ENDL;
-	}
-#endif
-
 	return result;
 }
 
 //decompress a block of LLSD from provided istream
 // not very efficient -- creats a copy of decompressed LLSD block in memory
 // and deserializes from that copy using LLSDSerialize
-bool unzip_llsd(LLSD& data, std::istream& is, S32 size)
+LLUZipHelper::EZipRresult LLUZipHelper::unzip_llsd(LLSD& data, std::istream& is, S32 size)
 {
 	U8* result = NULL;
 	U32 cur_size = 0;
@@ -2147,7 +2138,7 @@ bool unzip_llsd(LLSD& data, std::istream& is, S32 size)
 	U8 *in = new(std::nothrow) U8[size];
 	if (!in)
 	{
-		return false;
+		return ZR_MEM_ERROR;
 	}
 	is.read((char*) in, size); 
 
@@ -2171,7 +2162,7 @@ bool unzip_llsd(LLSD& data, std::istream& is, S32 size)
 			inflateEnd(&strm);
 			free(result);
 			delete [] in;
-			return false;
+			return ZR_DATA_ERROR;
 		}
 		
 		switch (ret)
@@ -2183,7 +2174,7 @@ bool unzip_llsd(LLSD& data, std::istream& is, S32 size)
 			inflateEnd(&strm);
 			free(result);
 			delete [] in;
-			return false;
+			return ZR_MEM_ERROR;
 			break;
 		}
 
@@ -2198,7 +2189,7 @@ bool unzip_llsd(LLSD& data, std::istream& is, S32 size)
 				free(result);
 			}
 			delete[] in;
-			return false;
+			return ZR_MEM_ERROR;
 		}
 		result = new_result;
 		memcpy(result+cur_size, out, have);
@@ -2212,33 +2203,50 @@ bool unzip_llsd(LLSD& data, std::istream& is, S32 size)
 	if (ret != Z_STREAM_END)
 	{
 		free(result);
-		return false;
+		return ZR_DATA_ERROR;
 	}
 
 	//result now points to the decompressed LLSD block
 	{
-		std::string res_str((char*) result, cur_size);
+		std::istringstream istr;
+		// Since we are using this for meshes, data we are dealing with tend to be large.
+		// So string can potentially fail to allocate, make sure this won't cause problems
+		try
+		{
+			std::string res_str((char*)result, cur_size);
+
+			std::string deprecated_header("<? LLSD/Binary ?>");
 
-		std::string deprecated_header("<? LLSD/Binary ?>");
+			if (res_str.substr(0, deprecated_header.size()) == deprecated_header)
+			{
+				res_str = res_str.substr(deprecated_header.size() + 1, cur_size);
+			}
+			cur_size = res_str.size();
 
-		if (res_str.substr(0, deprecated_header.size()) == deprecated_header)
+			istr.str(res_str);
+		}
+#ifdef LL_WINDOWS
+		catch (std::length_error)
 		{
-			res_str = res_str.substr(deprecated_header.size()+1, cur_size);
+			free(result);
+			return ZR_SIZE_ERROR;
+		}
+#endif
+		catch (std::bad_alloc)
+		{
+			free(result);
+			return ZR_MEM_ERROR;
 		}
-		cur_size = res_str.size();
 
-		std::istringstream istr(res_str);
-		
 		if (!LLSDSerialize::fromBinary(data, istr, cur_size))
 		{
-			LL_WARNS() << "Failed to unzip LLSD block" << LL_ENDL;
 			free(result);
-			return false;
-		}		
+			return ZR_PARSE_ERROR;
+		}
 	}
 
 	free(result);
-	return true;
+	return ZR_OK;
 }
 //This unzip function will only work with a gzip header and trailer - while the contents
 //of the actual compressed data is the same for either format (gzip vs zlib ), the headers
diff --git a/indra/llcommon/llsdserialize.h b/indra/llcommon/llsdserialize.h
index 23a0c8cfb1e332ea0346517c1cec74d2e33514b9..9f58d44fe7908b0fc70eb5eaba350a160feaea25 100644
--- a/indra/llcommon/llsdserialize.h
+++ b/indra/llcommon/llsdserialize.h
@@ -814,8 +814,24 @@ class LL_COMMON_API LLSDSerialize
 	}
 };
 
+class LL_COMMON_API LLUZipHelper : public LLRefCount
+{
+public:
+    typedef enum e_zip_result
+    {
+        ZR_OK = 0,
+        ZR_MEM_ERROR,
+        ZR_SIZE_ERROR,
+        ZR_DATA_ERROR,
+        ZR_PARSE_ERROR,
+    } EZipRresult;
+    // return OK or reason for failure
+    static EZipRresult unzip_llsd(LLSD& data, std::istream& is, S32 size);
+};
+
 //dirty little zip functions -- yell at davep
 LL_COMMON_API std::string zip_llsd(LLSD& data);
-LL_COMMON_API bool unzip_llsd(LLSD& data, std::istream& is, S32 size);
+
+
 LL_COMMON_API U8* unzip_llsdNavMesh( bool& valid, unsigned int& outsize,std::istream& is, S32 size);
 #endif // LL_LLSDSERIALIZE_H
diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp
index 5068c9c685e4a3871829f17985448d8fd05e89a1..b1be29f594ace4f9c576d0a904f9000d7519e72c 100644
--- a/indra/llmath/llvolume.cpp
+++ b/indra/llmath/llvolume.cpp
@@ -2367,9 +2367,10 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)
 	//input stream is now pointing at a zlib compressed block of LLSD
 	//decompress block
 	LLSD mdl;
-	if (!unzip_llsd(mdl, is, size))
+	U32 uzip_result = LLUZipHelper::unzip_llsd(mdl, is, size);
+	if (uzip_result != LLUZipHelper::ZR_OK)
 	{
-		LL_DEBUGS("MeshStreaming") << "Failed to unzip LLSD blob for LoD, will probably fetch from sim again." << LL_ENDL;
+		LL_DEBUGS("MeshStreaming") << "Failed to unzip LLSD blob for LoD with code " << uzip_result << " , will probably fetch from sim again." << LL_ENDL;
 		return false;
 	}
 	
diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp
index db6d00bc2cfc9b749e0ca7617ac6fdea0d166322..29af859cd002bea503532f74b2a2c7fb07c9f53b 100644
--- a/indra/llprimitive/llmodel.cpp
+++ b/indra/llprimitive/llmodel.cpp
@@ -1354,7 +1354,7 @@ bool LLModel::loadSkinInfo(LLSD& header, std::istream &is)
 
 		LLSD skin_data;
 
-		if (unzip_llsd(skin_data, is, size))
+		if (LLUZipHelper::unzip_llsd(skin_data, is, size) == LLUZipHelper::ZR_OK)
 		{
 			mSkinInfo.fromLLSD(skin_data);
 			return true;
@@ -1375,7 +1375,7 @@ bool LLModel::loadDecomposition(LLSD& header, std::istream& is)
 
 		LLSD data;
 
-		if (unzip_llsd(data, is, size))
+		if (LLUZipHelper::unzip_llsd(data, is, size) == LLUZipHelper::ZR_OK)
 		{
 			mPhysics.fromLLSD(data);
 			updateHullCenters();
diff --git a/indra/newview/llmaterialmgr.cpp b/indra/newview/llmaterialmgr.cpp
index f996557c17a01cb15e5593094b32befd0e00da58..3befdaf88d145fea21e21b02287d881d81886c07 100644
--- a/indra/newview/llmaterialmgr.cpp
+++ b/indra/newview/llmaterialmgr.cpp
@@ -410,9 +410,10 @@ void LLMaterialMgr::onGetResponse(bool success, const LLSD& content, const LLUUI
 	std::istringstream content_stream(content_string);
 
 	LLSD response_data;
-	if (!unzip_llsd(response_data, content_stream, content_binary.size()))
+	U32 uzip_result = LLUZipHelper::unzip_llsd(response_data, content_stream, content_binary.size());
+	if (uzip_result != LLUZipHelper::ZR_OK)
 	{
-		LL_WARNS("Materials") << "Cannot unzip LLSD binary content" << LL_ENDL;
+		LL_WARNS("Materials") << "Cannot unzip LLSD binary content: " << uzip_result << LL_ENDL;
 		return;
 	}
 
@@ -452,9 +453,10 @@ void LLMaterialMgr::onGetAllResponse(bool success, const LLSD& content, const LL
 	std::istringstream content_stream(content_string);
 
 	LLSD response_data;
-	if (!unzip_llsd(response_data, content_stream, content_binary.size()))
+	U32 uzip_result = LLUZipHelper::unzip_llsd(response_data, content_stream, content_binary.size());
+	if (uzip_result != LLUZipHelper::ZR_OK)
 	{
-		LL_WARNS("Materials") << "Cannot unzip LLSD binary content" << LL_ENDL;
+		LL_WARNS("Materials") << "Cannot unzip LLSD binary content: " << uzip_result << LL_ENDL;
 		return;
 	}
 
@@ -520,9 +522,10 @@ void LLMaterialMgr::onPutResponse(bool success, const LLSD& content)
 	std::istringstream content_stream(content_string);
 
 	LLSD response_data;
-	if (!unzip_llsd(response_data, content_stream, content_binary.size()))
+	U32 uzip_result = LLUZipHelper::unzip_llsd(response_data, content_stream, content_binary.size());
+	if (uzip_result != LLUZipHelper::ZR_OK)
 	{
-		LL_WARNS("Materials") << "Cannot unzip LLSD binary content" << LL_ENDL;
+		LL_WARNS("Materials") << "Cannot unzip LLSD binary content: " << uzip_result << LL_ENDL;
 		return;
 	}
 	else
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index 25bd0d855e80badece2612cc5bc8801d731c7723..51ca7a8a5140381b4e8db2a5d6dc315af5c0be97 100644
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -1765,9 +1765,11 @@ bool LLMeshRepoThread::skinInfoReceived(const LLUUID& mesh_id, U8* data, S32 dat
 
 		std::istringstream stream(res_str);
 
-		if (!unzip_llsd(skin, stream, data_size))
+		U32 uzip_result = LLUZipHelper::unzip_llsd(skin, stream, data_size);
+		if (uzip_result != LLUZipHelper::ZR_OK)
 		{
 			LL_WARNS(LOG_MESH) << "Mesh skin info parse error.  Not a valid mesh asset!  ID:  " << mesh_id
+							   << " uzip result" << uzip_result
 							   << LL_ENDL;
 			return false;
 		}
@@ -1797,9 +1799,11 @@ bool LLMeshRepoThread::decompositionReceived(const LLUUID& mesh_id, U8* data, S3
 
 		std::istringstream stream(res_str);
 
-		if (!unzip_llsd(decomp, stream, data_size))
+		U32 uzip_result = LLUZipHelper::unzip_llsd(decomp, stream, data_size);
+		if (uzip_result != LLUZipHelper::ZR_OK)
 		{
 			LL_WARNS(LOG_MESH) << "Mesh decomposition parse error.  Not a valid mesh asset!  ID:  " << mesh_id
+							   << " uzip result: " << uzip_result
 							   << LL_ENDL;
 			return false;
 		}
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index 7c6cce5c58fa795712e953e0a22a168bcfbdebcc..99358f44516410a3a509f500ac2fef96c0ca12e9 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -784,18 +784,21 @@ void LLViewerMedia::updateMedia(void *dummy_arg)
 				}
 			}
 			// update the audio stream here as well
+			static bool restore_parcel_audio = false;
 			if( !inworld_audio_enabled)
 			{
 				if(LLViewerMedia::isParcelAudioPlaying() && gAudiop && LLViewerMedia::hasParcelAudio())
 				{
 					LLViewerAudio::getInstance()->stopInternetStreamWithAutoFade();
+					restore_parcel_audio = true;
 				}
 			}
             else
             {
-                if(gAudiop && LLViewerMedia::hasParcelAudio() && gSavedSettings.getBOOL("MediaTentativeAutoPlay"))
+                if(gAudiop && LLViewerMedia::hasParcelAudio() && restore_parcel_audio && gSavedSettings.getBOOL("MediaTentativeAutoPlay"))
                 {
                     LLViewerAudio::getInstance()->startInternetStreamWithAutoFade(LLViewerMedia::getParcelAudioURL());
+                    restore_parcel_audio = false;
                 }
             }