diff options
| author | Shauren <shauren.trinity@gmail.com> | 2015-03-06 18:52:58 +0100 |
|---|---|---|
| committer | Shauren <shauren.trinity@gmail.com> | 2015-03-06 18:52:58 +0100 |
| commit | 854917a31aec84e101b0d895bd427c32cbdc6a55 (patch) | |
| tree | 09547241397d6bb65ca4c49b943063dc9b896da9 /src/server/shared | |
| parent | e49462fc1e7b5515977da03dbc3806ef639b983b (diff) | |
Core/DataStores: Added an extra safeguard for loading db2 hotfix locale tables - invalid row will no longer cause crashes
Diffstat (limited to 'src/server/shared')
| -rw-r--r-- | src/server/shared/DataStores/DB2StorageLoader.cpp | 58 | ||||
| -rw-r--r-- | src/server/shared/DataStores/DB2StorageLoader.h | 9 | ||||
| -rw-r--r-- | src/server/shared/DataStores/DB2Store.h | 58 |
3 files changed, 56 insertions, 69 deletions
diff --git a/src/server/shared/DataStores/DB2StorageLoader.cpp b/src/server/shared/DataStores/DB2StorageLoader.cpp index 67bf3008ca2..062cc251450 100644 --- a/src/server/shared/DataStores/DB2StorageLoader.cpp +++ b/src/server/shared/DataStores/DB2StorageLoader.cpp @@ -18,10 +18,7 @@ #include "Common.h" #include "DB2StorageLoader.h" #include "Database/DatabaseEnv.h" - -#include <cstdio> -#include <cstdlib> -#include <cstring> +#include "Log.h" DB2FileLoader::DB2FileLoader() { @@ -422,7 +419,7 @@ char* DB2FileLoader::AutoProduceStrings(const char* format, char* dataTable, uin return stringPool; } -char* DB2DatabaseLoader::Load(const char* format, int32 preparedStatement, uint32& records, char**& indexTable, char*& stringHolders, std::list<char*>& stringPool) +char* DB2DatabaseLoader::Load(const char* format, uint32 preparedStatement, uint32& records, char**& indexTable, char*& stringHolders, std::list<char*>& stringPool) { // Even though this query is executed only once, prepared statement is used to send data from mysql server in binary format PreparedQueryResult result = HotfixDatabase.Query(HotfixDatabase.GetPreparedStatement(preparedStatement)); @@ -563,7 +560,7 @@ char* DB2DatabaseLoader::Load(const char* format, int32 preparedStatement, uint3 return dataTable; } -void DB2DatabaseLoader::LoadStrings(const char* format, int32 preparedStatement, uint32 locale, char**& indexTable, std::list<char*>& stringPool) +void DB2DatabaseLoader::LoadStrings(const char* format, uint32 preparedStatement, uint32 locale, char**& indexTable, std::list<char*>& stringPool) { PreparedStatement* stmt = HotfixDatabase.GetPreparedStatement(preparedStatement); stmt->setString(0, localeNames[locale]); @@ -588,35 +585,40 @@ void DB2DatabaseLoader::LoadStrings(const char* format, int32 preparedStatement, uint32 indexValue = fields[0].GetUInt32(); // Attempt to overwrite existing data - char* dataValue = indexTable[indexValue]; - for (uint32 x = 0; x < fieldCount; x++) + if (char* dataValue = indexTable[indexValue]) { - switch (format[x]) + for (uint32 x = 0; x < fieldCount; x++) { - case FT_FLOAT: - case FT_IND: - case FT_INT: - offset += 4; - break; - case FT_BYTE: - offset += 1; - break; - case FT_STRING: + switch (format[x]) { - // fill only not filled entries - LocalizedString* db2str = *(LocalizedString**)(&dataValue[offset]); - if (db2str->Str[locale] == nullStr) - if (char* str = AddLocaleString(db2str, locale, fields[1 + stringFieldNumInRecord].GetString())) - stringPool.push_back(str); - - ++stringFieldNumInRecord; - offset += sizeof(char*); - break; + case FT_FLOAT: + case FT_IND: + case FT_INT: + offset += 4; + break; + case FT_BYTE: + offset += 1; + break; + case FT_STRING: + { + // fill only not filled entries + LocalizedString* db2str = *(LocalizedString**)(&dataValue[offset]); + if (db2str->Str[locale] == nullStr) + if (char* str = AddLocaleString(db2str, locale, fields[1 + stringFieldNumInRecord].GetString())) + stringPool.push_back(str); + + ++stringFieldNumInRecord; + offset += sizeof(char*); + break; + } } } + + ASSERT(offset == recordSize); } + else + TC_LOG_ERROR("sql.sql", "Hotfix locale table for storage %s references row that does not exist %u!", _storageName.c_str(), indexValue); - ASSERT(offset == recordSize); } while (result->NextRow()); return; diff --git a/src/server/shared/DataStores/DB2StorageLoader.h b/src/server/shared/DataStores/DB2StorageLoader.h index 0dc340868b7..31fc1d1e979 100644 --- a/src/server/shared/DataStores/DB2StorageLoader.h +++ b/src/server/shared/DataStores/DB2StorageLoader.h @@ -109,9 +109,14 @@ private: class DB2DatabaseLoader { public: - char* Load(const char* format, int32 preparedStatement, uint32& records, char**& indexTable, char*& stringHolders, std::list<char*>& stringPool); - void LoadStrings(const char* format, int32 preparedStatement, uint32 locale, char**& indexTable, std::list<char*>& stringPool); + explicit DB2DatabaseLoader(std::string const& storageName) : _storageName(storageName) { } + + char* Load(const char* format, uint32 preparedStatement, uint32& records, char**& indexTable, char*& stringHolders, std::list<char*>& stringPool); + void LoadStrings(const char* format, uint32 preparedStatement, uint32 locale, char**& indexTable, std::list<char*>& stringPool); static char* AddLocaleString(LocalizedString* holder, uint32 locale, std::string const& value); + +private: + std::string _storageName; }; #endif diff --git a/src/server/shared/DataStores/DB2Store.h b/src/server/shared/DataStores/DB2Store.h index 4abec4f5386..4ce77c1cd28 100644 --- a/src/server/shared/DataStores/DB2Store.h +++ b/src/server/shared/DataStores/DB2Store.h @@ -48,13 +48,20 @@ class DB2Storage : public DB2StorageBase public: typedef DBStorageIterator<T> iterator; - DB2Storage(char const* f, int32 preparedStmtIndex) - : _indexTableSize(0), _fieldCount(0), _format(f), _dataTable(nullptr), _dataTableEx(nullptr), _hotfixStatement(preparedStmtIndex) + DB2Storage(char const* fileName, char const* format, uint32 preparedStmtIndex) + : _fileName(fileName), _indexTableSize(0), _fieldCount(0), _format(format), _dataTable(nullptr), _dataTableEx(nullptr), _hotfixStatement(preparedStmtIndex) { _indexTable.AsT = NULL; } - ~DB2Storage() { Clear(); } + ~DB2Storage() + { + delete[] reinterpret_cast<char*>(_indexTable.AsT); + delete[] reinterpret_cast<char*>(_dataTable); + delete[] reinterpret_cast<char*>(_dataTableEx); + for (char* stringPool : _stringPoolList) + delete[] stringPool; + } bool HasRecord(uint32 id) const override { return id < _indexTableSize && _indexTable.AsT[id] != nullptr; } void WriteRecord(uint32 id, uint32 locale, ByteBuffer& buffer) const override @@ -105,14 +112,15 @@ public: void EraseRecord(uint32 id) override { if (id < _indexTableSize) _indexTable.AsT[id] = nullptr; } T const* LookupEntry(uint32 id) const { return (id >= _indexTableSize) ? nullptr : _indexTable.AsT[id]; } + std::string const& GetFileName() const { return _fileName; } uint32 GetNumRows() const { return _indexTableSize; } char const* GetFormat() const { return _format; } uint32 GetFieldCount() const { return _fieldCount; } - bool Load(char const* fn, uint32 locale) + bool Load(std::string const& path, uint32 locale) { DB2FileLoader db2; // Check if load was successful, only then continue - if (!db2.Load(fn, _format)) + if (!db2.Load((path + _fileName).c_str(), _format)) return false; _fieldCount = db2.GetCols(); @@ -135,7 +143,7 @@ public: return _indexTable.AsT != NULL; } - bool LoadStringsFrom(char const* fn, uint32 locale) + bool LoadStringsFrom(std::string const& path, uint32 locale) { // DB2 must be already loaded using Load if (!_indexTable.AsT) @@ -143,7 +151,7 @@ public: DB2FileLoader db2; // Check if load was successful, only then continue - if (!db2.Load(fn, _format)) + if (!db2.Load((path + _fileName).c_str(), _format)) return false; // load strings from another locale db2 data @@ -155,11 +163,8 @@ public: void LoadFromDB() { - if (_hotfixStatement == -1) - return; - char* extraStringHolders = nullptr; - if (char* dataTable = DB2DatabaseLoader().Load(_format, _hotfixStatement, _indexTableSize, _indexTable.AsChar, extraStringHolders, _stringPoolList)) + if (char* dataTable = DB2DatabaseLoader(_fileName).Load(_format, _hotfixStatement, _indexTableSize, _indexTable.AsChar, extraStringHolders, _stringPoolList)) _dataTableEx = reinterpret_cast<T*>(dataTable); if (extraStringHolders) @@ -168,42 +173,17 @@ public: void LoadStringsFromDB(uint32 locale) { - if (_hotfixStatement == -1) - return; - if (!DB2FileLoader::GetFormatStringFieldCount(_format)) return; - DB2DatabaseLoader().LoadStrings(_format, _hotfixStatement + 1, locale, _indexTable.AsChar, _stringPoolList); - } - - void Clear() - { - if (!_indexTable.AsT) - return; - - delete[] reinterpret_cast<char*>(_indexTable.AsT); - _indexTable.AsT = nullptr; - - delete[] reinterpret_cast<char*>(_dataTable); - _dataTable = nullptr; - - delete[] reinterpret_cast<char*>(_dataTableEx); - _dataTableEx = nullptr; - - while (!_stringPoolList.empty()) - { - delete[] _stringPoolList.front(); - _stringPoolList.pop_front(); - } - - _indexTableSize = 0; + DB2DatabaseLoader(_fileName).LoadStrings(_format, _hotfixStatement + 1, locale, _indexTable.AsChar, _stringPoolList); } iterator begin() { return iterator(_indexTable.AsT, _indexTableSize); } iterator end() { return iterator(_indexTable.AsT, _indexTableSize, _indexTableSize); } private: + std::string _fileName; uint32 _indexTableSize; uint32 _fieldCount; char const* _format; @@ -215,7 +195,7 @@ private: T* _dataTable; T* _dataTableEx; StringPoolList _stringPoolList; - int32 _hotfixStatement; + uint32 _hotfixStatement; }; #endif |
