diff options
| -rw-r--r-- | indra/llcommon/llsdserialize.cpp | 36 | 
1 files changed, 27 insertions, 9 deletions
| diff --git a/indra/llcommon/llsdserialize.cpp b/indra/llcommon/llsdserialize.cpp index ede212181d..71744aef3c 100644 --- a/indra/llcommon/llsdserialize.cpp +++ b/indra/llcommon/llsdserialize.cpp @@ -2217,24 +2217,42 @@ bool unzip_llsd(LLSD& data, std::istream& is, S32 size)  	//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); +		} +		catch (std::length_error)  		{ -			res_str = res_str.substr(deprecated_header.size()+1, cur_size); +			LL_DEBUGS("UNZIP") << "String we are creating is too big" << LL_ENDL; +			free(result); +			return false; +		} +		catch (std::bad_alloc) +		{ +			LL_DEBUGS("UNZIP") << "Failed to allocate for string" << LL_ENDL; +			free(result); +			return false;  		} -		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; +			LL_WARNS("UNZIP") << "Failed to unzip LLSD block" << LL_ENDL;  			free(result);  			return false; -		}		 +		}  	}  	free(result); | 
