Use sqlite3_bind_text to allow special characters in text

This commit is contained in:
Benau 2019-05-10 09:30:02 +08:00
parent ef9b80e5af
commit 005418d611
2 changed files with 60 additions and 15 deletions

View File

@ -710,7 +710,8 @@ void ServerLobby::cleanupDatabase()
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
/** Run simple query without bothering the result. */ /** Run simple query without bothering the result. */
void ServerLobby::easySQLQuery(const std::string& query) const void ServerLobby::easySQLQuery(const std::string& query,
std::function<void(sqlite3_stmt* stmt)> bind_function) const
{ {
if (!m_db) if (!m_db)
return; return;
@ -718,6 +719,8 @@ void ServerLobby::easySQLQuery(const std::string& query) const
int ret = sqlite3_prepare_v2(m_db, query.c_str(), -1, &stmt, 0); int ret = sqlite3_prepare_v2(m_db, query.c_str(), -1, &stmt, 0);
if (ret == SQLITE_OK) if (ret == SQLITE_OK)
{ {
if (bind_function)
bind_function(stmt);
ret = sqlite3_step(stmt); ret = sqlite3_step(stmt);
ret = sqlite3_finalize(stmt); ret = sqlite3_finalize(stmt);
if (ret != SQLITE_OK) if (ret != SQLITE_OK)
@ -805,15 +808,41 @@ void ServerLobby::writePlayerReport(Event* event)
"INSERT INTO %s " "INSERT INTO %s "
"(server_uid, reporter_ip, reporter_online_id, reporter_username, " "(server_uid, reporter_ip, reporter_online_id, reporter_username, "
"info, reporting_ip, reporting_online_id, reporting_username) " "info, reporting_ip, reporting_online_id, reporting_username) "
"VALUES (\"%s\", %u, %u, \"%s\", \"%s\", %u, %u, \"%s\");", "VALUES (?, %u, %u, ?, ?, %u, %u, ?);",
ServerConfig::m_player_reports_table.c_str(), ServerConfig::m_player_reports_table.c_str(),
ServerConfig::m_server_uid.c_str(),
reporter->getAddress().getIP(), reporter_npp->getOnlineId(), reporter->getAddress().getIP(), reporter_npp->getOnlineId(),
reporting_peer->getAddress().getIP(), reporting_npp->getOnlineId());
easySQLQuery(query, [reporter_npp, reporting_npp, info](sqlite3_stmt* stmt)
{
// SQLITE_TRANSIENT to copy string
if (sqlite3_bind_text(stmt, 1, ServerConfig::m_server_uid.c_str(),
-1, SQLITE_TRANSIENT) != SQLITE_OK)
{
Log::error("easySQLQuery", "Failed to bind %s.",
ServerConfig::m_server_uid.c_str());
}
if (sqlite3_bind_text(stmt, 2,
StringUtils::wideToUtf8(reporter_npp->getName()).c_str(), StringUtils::wideToUtf8(reporter_npp->getName()).c_str(),
-1, SQLITE_TRANSIENT) != SQLITE_OK)
{
Log::error("easySQLQuery", "Failed to bind %s.",
StringUtils::wideToUtf8(reporter_npp->getName()).c_str());
}
if (sqlite3_bind_text(stmt, 3,
StringUtils::wideToUtf8(info).c_str(), StringUtils::wideToUtf8(info).c_str(),
reporting_peer->getAddress().getIP(), reporting_npp->getOnlineId(), -1, SQLITE_TRANSIENT) != SQLITE_OK)
{
Log::error("easySQLQuery", "Failed to bind %s.",
StringUtils::wideToUtf8(info).c_str());
}
if (sqlite3_bind_text(stmt, 4,
StringUtils::wideToUtf8(reporting_npp->getName()).c_str(),
-1, SQLITE_TRANSIENT) != SQLITE_OK)
{
Log::error("easySQLQuery", "Failed to bind %s.",
StringUtils::wideToUtf8(reporting_npp->getName()).c_str()); StringUtils::wideToUtf8(reporting_npp->getName()).c_str());
easySQLQuery(query); }
});
#endif #endif
} // writePlayerReport } // writePlayerReport
@ -2834,13 +2863,28 @@ void ServerLobby::handleUnencryptedConnection(std::shared_ptr<STKPeer> peer,
std::string query = StringUtils::insertValues( std::string query = StringUtils::insertValues(
"INSERT INTO %s " "INSERT INTO %s "
"(host_id, ip, port, online_id, username, player_num, version, ping) " "(host_id, ip, port, online_id, username, player_num, version, ping) "
"VALUES (%u, %u, %u, %u, \"%s\", %u, \"%s\", %u);", "VALUES (%u, %u, %u, %u, ?, %u, ?, %u);",
m_server_stats_table.c_str(), peer->getHostId(), m_server_stats_table.c_str(), peer->getHostId(),
peer->getAddress().getIP(), peer->getAddress().getPort(), online_id, peer->getAddress().getIP(), peer->getAddress().getPort(), online_id,
player_count, peer->getAveragePing());
easySQLQuery(query, [peer](sqlite3_stmt* stmt)
{
if (sqlite3_bind_text(stmt, 1, StringUtils::wideToUtf8(
peer->getPlayerProfiles()[0]->getName()).c_str(),
-1, SQLITE_TRANSIENT) != SQLITE_OK)
{
Log::error("easySQLQuery", "Failed to bind %s.",
StringUtils::wideToUtf8( StringUtils::wideToUtf8(
peer->getPlayerProfiles()[0]->getName()).c_str(), player_count, peer->getPlayerProfiles()[0]->getName()).c_str());
peer->getUserVersion().c_str(), peer->getAveragePing()); }
easySQLQuery(query); if (sqlite3_bind_text(stmt, 2, peer->getUserVersion().c_str(),
-1, SQLITE_TRANSIENT) != SQLITE_OK)
{
Log::error("easySQLQuery", "Failed to bind %s.",
peer->getUserVersion().c_str());
}
}
);
#endif #endif
} // handleUnencryptedConnection } // handleUnencryptedConnection

View File

@ -28,11 +28,11 @@
#include <array> #include <array>
#include <atomic> #include <atomic>
#include <functional>
#include <map> #include <map>
#include <memory> #include <memory>
#include <mutex> #include <mutex>
#include <set> #include <set>
#include <tuple>
#ifdef ENABLE_SQLITE3 #ifdef ENABLE_SQLITE3
#include <sqlite3.h> #include <sqlite3.h>
@ -85,7 +85,8 @@ private:
void cleanupDatabase(); void cleanupDatabase();
void easySQLQuery(const std::string& query) const; void easySQLQuery(const std::string& query,
std::function<void(sqlite3_stmt* stmt)> bind_function = nullptr) const;
void checkTableExists(const std::string& table, bool& result); void checkTableExists(const std::string& table, bool& result);
#endif #endif