summaryrefslogtreecommitdiff
path: root/indra/llcommon
diff options
context:
space:
mode:
authorBrad Payne (Vir Linden) <vir@lindenlab.com>2018-03-02 13:00:18 +0000
committerBrad Payne (Vir Linden) <vir@lindenlab.com>2018-03-02 13:00:18 +0000
commit9f8c6ace4a72c6a44d062df15d78c123772a72c0 (patch)
tree500492208cabd8d896c19a88cf5bf7eddf66eeab /indra/llcommon
parent28b95e4975f2333c0eb590b29740c3ce491a934d (diff)
parentf8c76535a35aaf245e261357a59e977bac5b2501 (diff)
merge
Diffstat (limited to 'indra/llcommon')
-rw-r--r--indra/llcommon/llsdserialize.cpp65
-rw-r--r--indra/llcommon/llsdserialize.h18
-rw-r--r--indra/llcommon/llthread.cpp58
3 files changed, 75 insertions, 66 deletions
diff --git a/indra/llcommon/llsdserialize.cpp b/indra/llcommon/llsdserialize.cpp
index 3a219eb998..be54ed053b 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;
@@ -2144,7 +2135,11 @@ bool unzip_llsd(LLSD& data, std::istream& is, S32 size)
const U32 CHUNK = 65536;
- U8 *in = new U8[size];
+ U8 *in = new(std::nothrow) U8[size];
+ if (!in)
+ {
+ return ZR_MEM_ERROR;
+ }
is.read((char*) in, size);
U8 out[CHUNK];
@@ -2167,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)
@@ -2179,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;
}
@@ -2188,14 +2183,13 @@ bool unzip_llsd(LLSD& data, std::istream& is, S32 size)
U8* new_result = (U8*)realloc(result, cur_size + have);
if (new_result == NULL)
{
- LL_WARNS() << "Failed to unzip LLSD block: can't reallocate memory, current size: " << cur_size << " bytes; requested " << cur_size + have << " bytes." << LL_ENDL;
inflateEnd(&strm);
if (result)
{
free(result);
}
delete[] in;
- return false;
+ return ZR_MEM_ERROR;
}
result = new_result;
memcpy(result+cur_size, out, have);
@@ -2209,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)
+ 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();
+
+ istr.str(res_str);
+ }
+#ifdef LL_WINDOWS
+ catch (std::length_error)
+ {
+ free(result);
+ return ZR_SIZE_ERROR;
+ }
+#endif
+ catch (std::bad_alloc)
{
- res_str = res_str.substr(deprecated_header.size()+1, cur_size);
+ 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 23a0c8cfb1..9f58d44fe7 100644
--- a/indra/llcommon/llsdserialize.h
+++ b/indra/llcommon/llsdserialize.h
@@ -814,8 +814,24 @@ public:
}
};
+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/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp
index 00acfd1e4c..32e8ea9682 100644
--- a/indra/llcommon/llthread.cpp
+++ b/indra/llcommon/llthread.cpp
@@ -129,50 +129,32 @@ void *APR_THREAD_FUNC LLThread::staticRun(apr_thread_t *apr_threadp, void *datap
sThreadID = threadp->mID;
- try
+ // Run the user supplied function
+ do
{
- // Run the user supplied function
- do
+ try
{
- try
- {
- threadp->run();
- }
- catch (const LLContinueError &e)
- {
- LL_WARNS("THREAD") << "ContinueException on thread '" << threadp->mName <<
- "' reentering run(). Error what is: '" << e.what() << "'" << LL_ENDL;
- //output possible call stacks to log file.
- LLError::LLCallStacks::print();
-
- LOG_UNHANDLED_EXCEPTION("LLThread");
- continue;
- }
- break;
-
- } while (true);
+ threadp->run();
+ }
+ catch (const LLContinueError &e)
+ {
+ LL_WARNS("THREAD") << "ContinueException on thread '" << threadp->mName <<
+ "' reentering run(). Error what is: '" << e.what() << "'" << LL_ENDL;
+ //output possible call stacks to log file.
+ LLError::LLCallStacks::print();
- //LL_INFOS() << "LLThread::staticRun() Exiting: " << threadp->mName << LL_ENDL;
+ LOG_UNHANDLED_EXCEPTION("LLThread");
+ continue;
+ }
+ break;
- // We're done with the run function, this thread is done executing now.
- //NB: we are using this flag to sync across threads...we really need memory barriers here
- threadp->mStatus = STOPPED;
- }
- catch (std::bad_alloc)
- {
- threadp->mStatus = CRASHED;
- LLMemory::logMemoryInfo(TRUE);
+ } while (true);
- //output possible call stacks to log file.
- LLError::LLCallStacks::print();
+ //LL_INFOS() << "LLThread::staticRun() Exiting: " << threadp->mName << LL_ENDL;
- LL_ERRS("THREAD") << "Bad memory allocation in LLThread::staticRun() named '" << threadp->mName << "'!" << LL_ENDL;
- }
- catch (...)
- {
- threadp->mStatus = CRASHED;
- CRASH_ON_UNHANDLED_EXCEPTION("LLThread");
- }
+ // We're done with the run function, this thread is done executing now.
+ //NB: we are using this flag to sync across threads...we really need memory barriers here
+ threadp->mStatus = STOPPED;
delete threadp->mRecorder;
threadp->mRecorder = NULL;