From 8cf8c37c2ae1a991efb1de64bcbe0164f638a79a Mon Sep 17 00:00:00 2001 From: DarthArgus Date: Tue, 4 Oct 2016 17:22:58 -0500 Subject: [PATCH 1/9] tightening things up as i consider the best way to nuke non correlated people from orbit --- .../src/shared/ClientConnection.cpp | 27 +++++---- .../src/shared/ConfigLoginServer.cpp | 2 +- .../LoginServer/src/shared/LoginServer.cpp | 58 ++++++++++--------- 3 files changed, 48 insertions(+), 39 deletions(-) diff --git a/engine/server/application/LoginServer/src/shared/ClientConnection.cpp b/engine/server/application/LoginServer/src/shared/ClientConnection.cpp index 4af007c3..0cb75726 100755 --- a/engine/server/application/LoginServer/src/shared/ClientConnection.cpp +++ b/engine/server/application/LoginServer/src/shared/ClientConnection.cpp @@ -59,23 +59,23 @@ ClientConnection::~ClientConnection() void ClientConnection::onConnectionClosed() { // client has disconnected - if (m_clientId) + if (m_stationId) { - if (m_stationId) - { - DEBUG_REPORT_LOG(true, ("Client %lu disconnected\n", m_stationId)); - LOG("LoginClientConnection", - ("onConnectionClosed() for stationId (%lu) at IP (%s)", m_stationId, getRemoteAddress().c_str())); - } - - LoginServer::getInstance().removeClient(m_clientId); + DEBUG_REPORT_LOG(true, ("Client %lu disconnected\n", m_stationId)); + LOG("LoginClientConnection", ("onConnectionClosed() for stationId (%lu) at IP (%s)", m_stationId, getRemoteAddress().c_str())); } - if (!m_isValidated) { + LoginServer::getInstance().removeClient(m_clientId); + + if ((ConfigLoginServer::getValidateStationKey() || ConfigLoginServer::getDoSessionLogin()) && !m_isValidated) + { SessionApiClient *session = LoginServer::getInstance().getSessionApiClient(); if (session) + { session->dropClient(this); + } } + } //----------------------------------------------------------------------- @@ -194,7 +194,7 @@ void ClientConnection::validateClient(const std::string & id, const std::string if (!authURL.empty()) { // create the object - webAPI api(authURL); + webAPI api(authURL); // TODO: is loginserver single threaded? if so then let's make this static, and clear/reset it each run // add our data api.addJsonData("user_name", id); @@ -239,7 +239,8 @@ void ClientConnection::validateClient(const std::string & id, const std::string { if (suid == 0) { - if (uname.length() > MAX_ACCOUNT_NAME_LENGTH) { + if (uname.length() > MAX_ACCOUNT_NAME_LENGTH) + { uname.resize(MAX_ACCOUNT_NAME_LENGTH); } @@ -288,6 +289,8 @@ void ClientConnection::onCharacterDeletedFromCluster(const NetworkId & character if(f != m_charactersPendingDeletion.end()) { m_charactersPendingDeletion.erase(f); + + // TODO: send api request and decrement # characters on this account/subaccount } DeleteCharacterReplyMessage reply(DeleteCharacterReplyMessage::rc_OK); diff --git a/engine/server/application/LoginServer/src/shared/ConfigLoginServer.cpp b/engine/server/application/LoginServer/src/shared/ConfigLoginServer.cpp index 9b1d6c07..9c4dcd04 100755 --- a/engine/server/application/LoginServer/src/shared/ConfigLoginServer.cpp +++ b/engine/server/application/LoginServer/src/shared/ConfigLoginServer.cpp @@ -94,7 +94,7 @@ void ConfigLoginServer::install(void) KEY_BOOL (developmentMode, true); KEY_INT (databaseThreads, 1); KEY_BOOL (compressClientNetworkTraffic, true); - KEY_INT (metricsListenerPort, 2201); + KEY_INT (metricsListenerPort, 0); // defaults to 2201 but we don't use it KEY_FLOAT (defaultDBQueueUpdateTimeLimit, 0.25f); KEY_INT (disconnectSleepTime, 30000); KEY_INT (clusterGroup,1); diff --git a/engine/server/application/LoginServer/src/shared/LoginServer.cpp b/engine/server/application/LoginServer/src/shared/LoginServer.cpp index 6e41ffc5..d6525d55 100755 --- a/engine/server/application/LoginServer/src/shared/LoginServer.cpp +++ b/engine/server/application/LoginServer/src/shared/LoginServer.cpp @@ -160,7 +160,6 @@ LoginServer::LoginServer() : if (ConfigLoginServer::getDevelopmentMode()) { setup.port = ConfigLoginServer::getCentralServicePort(); - //setup.maxConnections = 1000; m_centralService = new Service(ConnectionAllocator(), setup); } @@ -219,6 +218,7 @@ int LoginServer::addClient(ClientConnection & client) { DEBUG_FATAL(client.getIsValidated(), ("Tried to add an already validated client?!")); //Perhaps add a debug only check to make sure a client connection isn't in twice...I'm not sure how that could happen. + static int nextClientId = 0; int tmp = ++nextClientId; m_clientMap[tmp] = &client; @@ -250,7 +250,7 @@ ClientConnection* LoginServer::getUnvalidatedClient(int clientId) void LoginServer::removeClient(int clientId) { - if (clientId) // yeah why bother if it's 0 or null? i realize 0 is a valid int but since previously the warning below fired if it was 0....yeah, no + if (clientId) // yeah why bother if it's null? { std::map::iterator i = m_clientMap.find(clientId); if (i != m_clientMap.end()) @@ -264,7 +264,7 @@ void LoginServer::removeClient(int clientId) } else { - WARNING_STRICT_FATAL(true, ("Tried to remove a client with client id == 0")); + DEBUG_WARNING(true, ("Tried to remove a client with client id == 0 (possibly DoS attack?)")); } } @@ -903,6 +903,7 @@ void LoginServer::receiveMessage(const MessageDispatch::Emitter & source, const if (conn) { // current restriction is that once per account event or item cannot require a "consuming" account feature id + // TODO: looks like this is where vet rewards are consumed...the one per account thing, here - session auth may be enough? uint32 const requiredAccountFeatureId = msg->getAccountFeatureId(); bool const consumeAccountFeatureId = msg->getConsumeAccountFeatureId(); if ((msg->getConsumeEvent() || msg->getConsumeItem()) && (requiredAccountFeatureId > 0) && consumeAccountFeatureId) @@ -1172,21 +1173,25 @@ void LoginServer::run(void) unsigned long totalTime = 0; // load authentication data and bind the monitor to the port - CMonitorAPI * mon = new CMonitorAPI("metricsAuthentication.cfg", ConfigLoginServer::getMetricsListenerPort()); - getInstance().m_soeMonitor = mon; - const char *masterChannel = "Population"; - mon->add(masterChannel, WORLD_COUNT_CHANNEL); - std::string host = NetworkHandler::getHostName().c_str(); - size_t dotPos = host.find("."); - if (dotPos != host.npos) - { - host = host.substr(0, dotPos - 1); - } - char tmpBuf[1024]; - IGNORE_RETURN(snprintf(tmpBuf, sizeof(tmpBuf), "LoginServer version %s on %s", ApplicationVersion::getInternalVersion(), host.c_str())); - mon->setDescription(WORLD_COUNT_CHANNEL, tmpBuf); + const int port = ConfigLoginServer::getMetricsListenerPort(); - mon->add("Galaxies", CLUSTER_COUNT_CHANNEL); + if (port) { + CMonitorAPI *mon = new CMonitorAPI("metricsAuthentication.cfg", ConfigLoginServer::getMetricsListenerPort()); + getInstance().m_soeMonitor = mon; + const char *masterChannel = "Population"; + mon->add(masterChannel, WORLD_COUNT_CHANNEL); + std::string host = NetworkHandler::getHostName().c_str(); + size_t dotPos = host.find("."); + if (dotPos != host.npos) { + host = host.substr(0, dotPos - 1); + } + char tmpBuf[1024]; + IGNORE_RETURN(snprintf(tmpBuf, sizeof(tmpBuf), "LoginServer version %s on %s", ApplicationVersion::getInternalVersion(), host + .c_str())); + mon->setDescription(WORLD_COUNT_CHANNEL, tmpBuf); + + mon->add("Galaxies", CLUSTER_COUNT_CHANNEL); + } while (!getInstance().done) { @@ -1224,16 +1229,17 @@ void LoginServer::run(void) NetworkHandler::clearBytesThisFrame(); - mon->set(WORLD_COUNT_CHANNEL, static_cast(getInstance().m_clientMap.size())); - int count = 0; - ClusterListType::const_iterator i; - for (i = getInstance().m_clusterList.begin(); i != getInstance().m_clusterList.end(); ++i) - { - if ((*i)->m_connected) - ++count; + if (port) { + mon->set(WORLD_COUNT_CHANNEL, static_cast(getInstance().m_clientMap.size())); + int count = 0; + ClusterListType::const_iterator i; + for (i = getInstance().m_clusterList.begin(); i != getInstance().m_clusterList.end(); ++i) { + if ((*i)->m_connected) + ++count; + } + mon->set(CLUSTER_COUNT_CHANNEL, count); + mon->Update(); } - mon->set(CLUSTER_COUNT_CHANNEL, count); - mon->Update(); } NetworkHandler::update(); From 69cdb67d7cd9e7680fe7675adf60ab3437cba268 Mon Sep 17 00:00:00 2001 From: DarthArgus Date: Wed, 5 Oct 2016 10:26:49 -0500 Subject: [PATCH 2/9] cleanup? neeed to investigate how best to close hanging open connections here or in udp lib, also a method to bypass service callbacks when blocking ddoses --- .../LoginServer/src/shared/LoginServer.cpp | 28 +++++++++++-------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/engine/server/application/LoginServer/src/shared/LoginServer.cpp b/engine/server/application/LoginServer/src/shared/LoginServer.cpp index d6525d55..df7e0cfd 100755 --- a/engine/server/application/LoginServer/src/shared/LoginServer.cpp +++ b/engine/server/application/LoginServer/src/shared/LoginServer.cpp @@ -14,7 +14,11 @@ #include "ConsoleManager.h" #include "CSToolConnection.h" #include "DatabaseConnection.h" + +#ifdef _DEBUG #include "LoginServerRemoteDebugSetup.h" +#endif + #include "MonAPI2/MonitorAPI.h" #include "PingConnection.h" #include "PurgeManager.h" @@ -250,21 +254,14 @@ ClientConnection* LoginServer::getUnvalidatedClient(int clientId) void LoginServer::removeClient(int clientId) { - if (clientId) // yeah why bother if it's null? + std::map::iterator i = m_clientMap.find(clientId); + if (i != m_clientMap.end()) { - std::map::iterator i = m_clientMap.find(clientId); - if (i != m_clientMap.end()) + if (i->second->getIsValidated()) { - if (i->second->getIsValidated()) - { - IGNORE_RETURN(m_validatedClientMap.erase(i->second->getStationId())); - } - IGNORE_RETURN(m_clientMap.erase(clientId)); + IGNORE_RETURN(m_validatedClientMap.erase(i->second->getStationId())); } - } - else - { - DEBUG_WARNING(true, ("Tried to remove a client with client id == 0 (possibly DoS attack?)")); + IGNORE_RETURN(m_clientMap.erase(clientId)); } } @@ -1160,7 +1157,11 @@ void LoginServer::validateAccountForTransfer(const TransferRequestMoveValidation void LoginServer::run(void) { NetworkHandler::install(); + +#ifdef _DEBUG LoginServerRemoteDebugSetup::install(); +#endif + DatabaseConnection::getInstance().connect(); DatabaseConnection::getInstance().requestClusterList(); SetupSharedLog::install("LoginServer"); @@ -1246,7 +1247,10 @@ void LoginServer::run(void) ConsoleManager::remove(); DatabaseConnection::getInstance().disconnect(); + +#ifdef _DEBUG LoginServerRemoteDebugSetup::remove(); +#endif SetupSharedLog::remove(); NetworkHandler::remove(); From 4a89f376e807374a835bb56f39fdda548c9a0ce1 Mon Sep 17 00:00:00 2001 From: DarthArgus Date: Wed, 5 Oct 2016 10:29:54 -0500 Subject: [PATCH 3/9] hopefully fix a mistake --- .../server/application/LoginServer/src/shared/LoginServer.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/engine/server/application/LoginServer/src/shared/LoginServer.cpp b/engine/server/application/LoginServer/src/shared/LoginServer.cpp index df7e0cfd..eacfee13 100755 --- a/engine/server/application/LoginServer/src/shared/LoginServer.cpp +++ b/engine/server/application/LoginServer/src/shared/LoginServer.cpp @@ -1175,9 +1175,10 @@ void LoginServer::run(void) // load authentication data and bind the monitor to the port const int port = ConfigLoginServer::getMetricsListenerPort(); + CMonitorAPI *mon = nullptr; if (port) { - CMonitorAPI *mon = new CMonitorAPI("metricsAuthentication.cfg", ConfigLoginServer::getMetricsListenerPort()); + mon = new CMonitorAPI("metricsAuthentication.cfg", ConfigLoginServer::getMetricsListenerPort()); getInstance().m_soeMonitor = mon; const char *masterChannel = "Population"; mon->add(masterChannel, WORLD_COUNT_CHANNEL); From bde2d642edebd66f94ae125f7ce21f8c57cf69e7 Mon Sep 17 00:00:00 2001 From: DarthArgus Date: Wed, 5 Oct 2016 21:28:28 -0500 Subject: [PATCH 4/9] cleanup --- .../LoginServer/src/shared/LoginServer.cpp | 20 +------------------ .../3rd/library/udplibrary/UdpLibrary.cpp | 2 +- .../3rd/library/udplibrary/UdpLibrary.hpp | 2 +- 3 files changed, 3 insertions(+), 21 deletions(-) diff --git a/engine/server/application/LoginServer/src/shared/LoginServer.cpp b/engine/server/application/LoginServer/src/shared/LoginServer.cpp index eacfee13..17e7e760 100755 --- a/engine/server/application/LoginServer/src/shared/LoginServer.cpp +++ b/engine/server/application/LoginServer/src/shared/LoginServer.cpp @@ -1076,25 +1076,7 @@ void LoginServer::validateAccount(const StationId& stationId, uint32 clusterId, // Check cluster npe user limit if (cle->m_numTutorialPlayers > cle->m_onlineTutorialLimit) { - canCreateRegular = false; - canCreateJedi = false; - } - - // limit login/character creation based on subscription feature bits - if (((subscriptionBits & ClientSubscriptionFeature::FreeTrial) != 0) - && ((subscriptionBits & ClientSubscriptionFeature::Base) == 0)) - { - // Check cluster free trial user limit - if (cle->m_numFreeTrialPlayers > cle->m_onlineFreeTrialLimit) - { - canLogin = false; - } - // Check cluster free trial character creation - if (!cle->m_freeTrialCanCreateChar) - { - canCreateRegular = false; - canCreateJedi = false; - } + canLogin = false; } } diff --git a/external/3rd/library/udplibrary/UdpLibrary.cpp b/external/3rd/library/udplibrary/UdpLibrary.cpp index 945b3bf4..2971bb9c 100755 --- a/external/3rd/library/udplibrary/UdpLibrary.cpp +++ b/external/3rd/library/udplibrary/UdpLibrary.cpp @@ -1022,7 +1022,7 @@ void UdpManager::ProcessRawPacket(const PacketHistoryEntry *e) { if (e->mBuffer[0] == 0 && e->mBuffer[1] == UdpConnection::cUdpPacketPortAlive) return; // port-alive packets are not supposed to reach the destination machine, but on the odd chance they do, pretend like they never existed - + UdpConnection *con = AddressGetConnection(e->mIp, e->mPort); if (con == nullptr) diff --git a/external/3rd/library/udplibrary/UdpLibrary.hpp b/external/3rd/library/udplibrary/UdpLibrary.hpp index 86534a73..52922dab 100644 --- a/external/3rd/library/udplibrary/UdpLibrary.hpp +++ b/external/3rd/library/udplibrary/UdpLibrary.hpp @@ -1078,7 +1078,7 @@ class UdpConnection : public PriorityQueueMember, public AddressHashTableMember, , cDisconnectReasonNewConnectionAttempt, cDisconnectReasonConnectionRefused , cDisconnectReasonMutualConnectError, cDisconnectReasonConnectingToSelf , cDisconnectReasonReliableOverflow - , cDisconnectReasonCount, cDisconnectReasonDosAttack }; + , cDisconnectReasonDosAttack, cDisconnectReasonCount }; // standard AddRef/Release scheme void AddRef(); From 8561df0332d12b855c6220c34de3e9b94c9dc9cc Mon Sep 17 00:00:00 2001 From: DarthArgus Date: Thu, 6 Oct 2016 21:10:29 +0000 Subject: [PATCH 5/9] revert login --- .../LoginServer/src/shared/LoginServer.cpp | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/engine/server/application/LoginServer/src/shared/LoginServer.cpp b/engine/server/application/LoginServer/src/shared/LoginServer.cpp index 17e7e760..eacfee13 100755 --- a/engine/server/application/LoginServer/src/shared/LoginServer.cpp +++ b/engine/server/application/LoginServer/src/shared/LoginServer.cpp @@ -1076,7 +1076,25 @@ void LoginServer::validateAccount(const StationId& stationId, uint32 clusterId, // Check cluster npe user limit if (cle->m_numTutorialPlayers > cle->m_onlineTutorialLimit) { - canLogin = false; + canCreateRegular = false; + canCreateJedi = false; + } + + // limit login/character creation based on subscription feature bits + if (((subscriptionBits & ClientSubscriptionFeature::FreeTrial) != 0) + && ((subscriptionBits & ClientSubscriptionFeature::Base) == 0)) + { + // Check cluster free trial user limit + if (cle->m_numFreeTrialPlayers > cle->m_onlineFreeTrialLimit) + { + canLogin = false; + } + // Check cluster free trial character creation + if (!cle->m_freeTrialCanCreateChar) + { + canCreateRegular = false; + canCreateJedi = false; + } } } From 6dd6163f86bf79747ea3e6245ebf23be947d46dc Mon Sep 17 00:00:00 2001 From: DarthArgus Date: Fri, 7 Oct 2016 01:35:42 +0000 Subject: [PATCH 6/9] Revert "revert login" This reverts commit 8561df0332d12b855c6220c34de3e9b94c9dc9cc. --- .../LoginServer/src/shared/LoginServer.cpp | 20 +------------------ 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/engine/server/application/LoginServer/src/shared/LoginServer.cpp b/engine/server/application/LoginServer/src/shared/LoginServer.cpp index eacfee13..17e7e760 100755 --- a/engine/server/application/LoginServer/src/shared/LoginServer.cpp +++ b/engine/server/application/LoginServer/src/shared/LoginServer.cpp @@ -1076,25 +1076,7 @@ void LoginServer::validateAccount(const StationId& stationId, uint32 clusterId, // Check cluster npe user limit if (cle->m_numTutorialPlayers > cle->m_onlineTutorialLimit) { - canCreateRegular = false; - canCreateJedi = false; - } - - // limit login/character creation based on subscription feature bits - if (((subscriptionBits & ClientSubscriptionFeature::FreeTrial) != 0) - && ((subscriptionBits & ClientSubscriptionFeature::Base) == 0)) - { - // Check cluster free trial user limit - if (cle->m_numFreeTrialPlayers > cle->m_onlineFreeTrialLimit) - { - canLogin = false; - } - // Check cluster free trial character creation - if (!cle->m_freeTrialCanCreateChar) - { - canCreateRegular = false; - canCreateJedi = false; - } + canLogin = false; } } From 34a391db304c57e693994a0e0d5b6ff55a140ab1 Mon Sep 17 00:00:00 2001 From: DarthArgus Date: Fri, 7 Oct 2016 01:42:13 +0000 Subject: [PATCH 7/9] remove deprecated c hooks --- .../src/linux/OsNewDel.cpp | 41 ------------------- 1 file changed, 41 deletions(-) diff --git a/engine/shared/library/sharedMemoryManager/src/linux/OsNewDel.cpp b/engine/shared/library/sharedMemoryManager/src/linux/OsNewDel.cpp index 29280ef8..9ab1fce2 100755 --- a/engine/shared/library/sharedMemoryManager/src/linux/OsNewDel.cpp +++ b/engine/shared/library/sharedMemoryManager/src/linux/OsNewDel.cpp @@ -16,47 +16,6 @@ static MemoryManager memoryManager __attribute__ ((init_priority (101))); -#define USE_LIBC_MALLOC_HOOKS 0 - -#if USE_LIBC_MALLOC_HOOKS -extern "C" -{ - void memoryManagerFreeHook(__malloc_ptr_t __ptr, __const __malloc_ptr_t) - { - delete[] (char *)__ptr; - } - - __malloc_ptr_t memoryManagerMallocHook(size_t __size, const __malloc_ptr_t) - { - return new char[__size]; - } - - __malloc_ptr_t memoryManagerReallocHook(__malloc_ptr_t __ptr, size_t size, __const __malloc_ptr_t) - { - if(! __ptr) - return new char[size]; - - return MemoryManager::reallocate(__ptr, size); - } - - __malloc_ptr_t memoryManagerMemAlignHook(size_t alignment, size_t size, __const __malloc_ptr_t) - { - DEBUG_FATAL(true, ("memalign not implemented!")); - return new char[size]; - } - - static void memoryManagerMallocInitializeHook(void) - { - __free_hook = memoryManagerFreeHook; - __malloc_hook = memoryManagerMallocHook; - __realloc_hook = memoryManagerReallocHook; - __memalign_hook = memoryManagerMemAlignHook; - } - void (*__malloc_initialize_hook) (void) = memoryManagerMallocInitializeHook; -} - -#endif//USE_LIBC_MALLOC_HOOKS - // ====================================================================== void *operator new(size_t size, MemoryManagerNotALeak) From b1694841f2564e49a3477ffc9f0495b35880efe5 Mon Sep 17 00:00:00 2001 From: DarthArgus Date: Sun, 9 Oct 2016 20:05:20 +0000 Subject: [PATCH 8/9] ignore pvs files --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 1431e7be..b112824a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ *.geany +PVS* *.cfg *.cmd .project From f21883785d80d596dbbea6be7e2b711a89ec5495 Mon Sep 17 00:00:00 2001 From: DarthArgus Date: Sun, 16 Oct 2016 05:43:39 +0000 Subject: [PATCH 9/9] auto-truncate too long strings before insertion into the db --- .../src/shared/core/DbBindableString.h | 51 +++++++++++++------ .../src/shared/core/DbBindableUnicode.h | 20 +++++--- 2 files changed, 49 insertions(+), 22 deletions(-) diff --git a/engine/shared/library/sharedDatabaseInterface/src/shared/core/DbBindableString.h b/engine/shared/library/sharedDatabaseInterface/src/shared/core/DbBindableString.h index 2548990e..7a1d2e04 100755 --- a/engine/shared/library/sharedDatabaseInterface/src/shared/core/DbBindableString.h +++ b/engine/shared/library/sharedDatabaseInterface/src/shared/core/DbBindableString.h @@ -249,33 +249,52 @@ namespace DB return; } - // the following is strncpy, but keeps a count of the number of characters - unsigned int i; - for (i=0;i= S) { + WARNING(true, ("Attmpted to insert %s which is too long. Truncating.", buffer)); + indicator = S; + memcpy(m_value, buffer, indicator-1); + } else { + indicator = bufsize; + memcpy(m_value, buffer, indicator); } - FATAL((i==S+1) && (m_value[S]!='\0'),("Attempt to save string \"%s\" to the database. It is too long for the column.",buffer)); - indicator=i; // set indicator to actual length of string -// m_value[S]='\0'; // guarantee nullptr terminator -- uncomment if you remove the above FATAL + + m_value[indicator] = '\0'; } template void BindableString::setValue(const Unicode::String &buffer) { - FATAL(buffer.size()>S,("Attempt to save a Unicode::String \"%s\"that is too long to the database.", Unicode::wideToNarrow(buffer).c_str())); - strncpy(m_value, Unicode::wideToNarrow(buffer).c_str(), S+1); - indicator=buffer.size(); + size_t bufsize = buffer.size(); + + if (bufsize >= S) { + WARNING(true, ("Attmpted to insert %s which is too long. Truncating.", buffer.c_str())); + indicator = S; + memcpy(m_value, Unicode::wideToNarrow(buffer).c_str(), indicator-1); + } else { + indicator = bufsize; + memcpy(m_value, Unicode::wideToNarrow(buffer).c_str(), indicator); + } + + m_value[indicator] = '\0'; } template void BindableString::setValue(const std::string &buffer) { - FATAL(buffer.length()>S,("Attempt to save a std::string \"%s\"that is too long to the database.", buffer.c_str())); - strncpy(m_value, buffer.c_str(), S+1); - indicator=buffer.length(); + size_t bufsize = buffer.size(); + + if (bufsize >= S) { + WARNING(true, ("Attmpted to insert %s which is too long. Truncating.", buffer.c_str())); + indicator = S; + memcpy(m_value, buffer.c_str(), indicator-1); + } else { + indicator = bufsize; + memcpy(m_value, buffer.c_str(), indicator); + } + + m_value[indicator] = '\0'; } template diff --git a/engine/shared/library/sharedDatabaseInterface/src/shared/core/DbBindableUnicode.h b/engine/shared/library/sharedDatabaseInterface/src/shared/core/DbBindableUnicode.h index 544ead4c..fba31be0 100755 --- a/engine/shared/library/sharedDatabaseInterface/src/shared/core/DbBindableUnicode.h +++ b/engine/shared/library/sharedDatabaseInterface/src/shared/core/DbBindableUnicode.h @@ -192,12 +192,20 @@ namespace DB template void BindableUnicode::setValue(const Unicode::String &buffer) { - FATAL(buffer.size()>S,("Attempt to save a Unicode::String \"%s\"that is too long to the database.", Unicode::wideToNarrow(buffer).c_str())); - - std::string str; - str = Unicode::wideToUTF8(buffer, str); - indicator = (str.size()>S ? S : str.size()); - memcpy(m_value, str.c_str(),indicator); + std::string str; + str = Unicode::wideToUTF8(buffer, str); + + size_t bufsize = str.size(); + + if (bufsize >= S) { + WARNING(true, ("Attmpted to insert %s which is too long. Truncating.", buffer.c_str())); + indicator = S; + memcpy(m_value, str.c_str(), indicator-1); + } else { + indicator = bufsize; + memcpy(m_value, str.c_str(), indicator); + } + m_value[indicator] = '\0'; }