diff options
author | andreykproductengine <andreykproductengine@lindenlab.com> | 2018-01-02 20:31:23 +0200 |
---|---|---|
committer | andreykproductengine <andreykproductengine@lindenlab.com> | 2018-01-02 20:31:23 +0200 |
commit | a35008993eef5b1fee5695804c83050cf922d146 (patch) | |
tree | e7e74e433c49f6b6759e8d144ef2f1ba30ea48d8 | |
parent | 2897ea5c5b997ce19b9b7687a5bbc428c523c6ab (diff) |
MAINT-8022 String crashes in unzip_llsd
-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); |