diff options
author | andreykproductengine <andreykproductengine@lindenlab.com> | 2017-11-06 16:46:16 +0200 |
---|---|---|
committer | andreykproductengine <andreykproductengine@lindenlab.com> | 2017-11-06 16:46:16 +0200 |
commit | 7161619d6c0ee790c5741d0df028e428052e5fcc (patch) | |
tree | c6bb2f0e47e3fe28256a89226c5b82bf92d043cc | |
parent | ece5e6b827ad278fec4a8c859fe97977cc4f1fda (diff) |
MAINT-7978 - Fixed allocation crash in doRead(), workers should never crash
-rw-r--r-- | indra/newview/lltexturecache.cpp | 112 |
1 files changed, 68 insertions, 44 deletions
diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp index 062ee37864..435d833345 100644 --- a/indra/newview/lltexturecache.cpp +++ b/indra/newview/lltexturecache.cpp @@ -387,22 +387,35 @@ bool LLTextureCacheRemoteWorker::doRead() } // Allocate read buffer mReadData = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), mDataSize); - S32 bytes_read = LLAPRFile::readEx(local_filename, - mReadData, mOffset, mDataSize, mCache->getLocalAPRFilePool()); - if (bytes_read != mDataSize) + + if (mReadData) { - LL_WARNS() << "Error reading file from local cache: " << local_filename - << " Bytes: " << mDataSize << " Offset: " << mOffset + S32 bytes_read = LLAPRFile::readEx( local_filename, + mReadData, + mOffset, + mDataSize, + mCache->getLocalAPRFilePool()); + + if (bytes_read != mDataSize) + { + LL_WARNS() << "Error reading file from local cache: " << local_filename + << " Bytes: " << mDataSize << " Offset: " << mOffset << " / " << mDataSize << LL_ENDL; - mDataSize = 0; - FREE_MEM(LLImageBase::getPrivatePool(), mReadData); - mReadData = NULL; + mDataSize = 0; + FREE_MEM(LLImageBase::getPrivatePool(), mReadData); + mReadData = NULL; + } + else + { + mImageSize = local_size; + mImageLocal = TRUE; + } } else { - //LL_INFOS() << "texture " << mID.asString() << " found in local_assets" << LL_ENDL; - mImageSize = local_size; - mImageLocal = TRUE; + LL_WARNS() << "Error allocating memory for cache: " << local_filename + << " of size: " << mDataSize << LL_ENDL; + mDataSize = 0; } // We're done... done = true; @@ -477,44 +490,55 @@ bool LLTextureCacheRemoteWorker::doRead() // Reserve the whole data buffer first U8* data = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), mDataSize); - - // Set the data file pointers taking the read offset into account. 2 cases: - if (mOffset < TEXTURE_CACHE_ENTRY_SIZE) + if (data) { - // Offset within the header record. That means we read something from the header cache. - // Note: most common case is (mOffset = 0), so this is the "normal" code path. - data_offset = TEXTURE_CACHE_ENTRY_SIZE - mOffset; // i.e. TEXTURE_CACHE_ENTRY_SIZE if mOffset nul (common case) - file_offset = 0; - file_size = mDataSize - data_offset; - // Copy the raw data we've been holding from the header cache into the new sized buffer - llassert_always(mReadData); - memcpy(data, mReadData, data_offset); - FREE_MEM(LLImageBase::getPrivatePool(), mReadData); - mReadData = NULL; - } - else - { - // Offset bigger than the header record. That means we haven't read anything yet. - data_offset = 0; - file_offset = mOffset - TEXTURE_CACHE_ENTRY_SIZE; - file_size = mDataSize; - // No data from header cache to copy in that case, we skipped it all - } + // Set the data file pointers taking the read offset into account. 2 cases: + if (mOffset < TEXTURE_CACHE_ENTRY_SIZE) + { + // Offset within the header record. That means we read something from the header cache. + // Note: most common case is (mOffset = 0), so this is the "normal" code path. + data_offset = TEXTURE_CACHE_ENTRY_SIZE - mOffset; // i.e. TEXTURE_CACHE_ENTRY_SIZE if mOffset nul (common case) + file_offset = 0; + file_size = mDataSize - data_offset; + // Copy the raw data we've been holding from the header cache into the new sized buffer + llassert_always(mReadData); + memcpy(data, mReadData, data_offset); + FREE_MEM(LLImageBase::getPrivatePool(), mReadData); + mReadData = NULL; + } + else + { + // Offset bigger than the header record. That means we haven't read anything yet. + data_offset = 0; + file_offset = mOffset - TEXTURE_CACHE_ENTRY_SIZE; + file_size = mDataSize; + // No data from header cache to copy in that case, we skipped it all + } - // Now use that buffer as the object read buffer - llassert_always(mReadData == NULL); - mReadData = data; + // Now use that buffer as the object read buffer + llassert_always(mReadData == NULL); + mReadData = data; - // Read the data at last - S32 bytes_read = LLAPRFile::readEx(filename, - mReadData + data_offset, - file_offset, file_size, - mCache->getLocalAPRFilePool()); - if (bytes_read != file_size) + // Read the data at last + S32 bytes_read = LLAPRFile::readEx(filename, + mReadData + data_offset, + file_offset, file_size, + mCache->getLocalAPRFilePool()); + if (bytes_read != file_size) + { + LL_WARNS() << "LLTextureCacheWorker: " << mID + << " incorrect number of bytes read from body: " << bytes_read + << " / " << file_size << LL_ENDL; + FREE_MEM(LLImageBase::getPrivatePool(), mReadData); + mReadData = NULL; + mDataSize = -1; // failed + done = true; + } + } + else { LL_WARNS() << "LLTextureCacheWorker: " << mID - << " incorrect number of bytes read from body: " << bytes_read - << " / " << file_size << LL_ENDL; + << " failed to allocate memory for reading: " << mDataSize << LL_ENDL; FREE_MEM(LLImageBase::getPrivatePool(), mReadData); mReadData = NULL; mDataSize = -1; // failed |