summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandreykproductengine <andreykproductengine@lindenlab.com>2018-01-02 20:31:23 +0200
committerandreykproductengine <andreykproductengine@lindenlab.com>2018-01-02 20:31:23 +0200
commita35008993eef5b1fee5695804c83050cf922d146 (patch)
treee7e74e433c49f6b6759e8d144ef2f1ba30ea48d8
parent2897ea5c5b997ce19b9b7687a5bbc428c523c6ab (diff)
MAINT-8022 String crashes in unzip_llsd
-rw-r--r--indra/llcommon/llsdserialize.cpp36
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);