aboutsummaryrefslogtreecommitdiff
path: root/src/server/shared
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2015-03-06 18:52:58 +0100
committerShauren <shauren.trinity@gmail.com>2015-03-06 18:52:58 +0100
commit854917a31aec84e101b0d895bd427c32cbdc6a55 (patch)
tree09547241397d6bb65ca4c49b943063dc9b896da9 /src/server/shared
parente49462fc1e7b5515977da03dbc3806ef639b983b (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.cpp58
-rw-r--r--src/server/shared/DataStores/DB2StorageLoader.h9
-rw-r--r--src/server/shared/DataStores/DB2Store.h58
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