aboutsummaryrefslogtreecommitdiff
path: root/src/modules/extra/m_mysql.cpp
diff options
context:
space:
mode:
authorGravatar Sadie Powell2019-09-23 00:37:33 +0100
committerGravatar Sadie Powell2019-09-23 00:37:33 +0100
commit8848169e8b42b5ed85837efd3b3f9e36ffbada1b (patch)
tree04babb46ea381f254589b12288f121d53338cb67 /src/modules/extra/m_mysql.cpp
parentInstall libc++abi-dev on Travis. (diff)
parentLower the acceptable drift for clocks on link. (diff)
Merge branch 'insp3' into master.
Diffstat (limited to 'src/modules/extra/m_mysql.cpp')
-rw-r--r--src/modules/extra/m_mysql.cpp58
1 files changed, 35 insertions, 23 deletions
diff --git a/src/modules/extra/m_mysql.cpp b/src/modules/extra/m_mysql.cpp
index 90ed1a82c..d3df58833 100644
--- a/src/modules/extra/m_mysql.cpp
+++ b/src/modules/extra/m_mysql.cpp
@@ -246,6 +246,31 @@ class MySQLresult : public SQL::Result
*/
class SQLConnection : public SQL::Provider
{
+ private:
+ bool EscapeString(SQL::Query* query, const std::string& in, std::string& out)
+ {
+ // In the worst case each character may need to be encoded as using two bytes and one
+ // byte is the NUL terminator.
+ std::vector<char> buffer(in.length() * 2 + 1);
+
+ // The return value of mysql_escape_string() is either an error or the length of the
+ // encoded string not including the NUL terminator.
+ //
+ // Unfortunately, someone genius decided that mysql_escape_string should return an
+ // unsigned type even though -1 is returned on error so checking whether an error
+ // happened is a bit cursed.
+ unsigned long escapedsize = mysql_escape_string(&buffer[0], in.c_str(), in.length());
+ if (escapedsize == static_cast<unsigned long>(-1))
+ {
+ SQL::Error err(SQL::QSEND_FAIL, InspIRCd::Format("%u: %s", mysql_errno(connection), mysql_error(connection)));
+ query->OnError(err);
+ return false;
+ }
+
+ out.append(&buffer[0], escapedsize);
+ return true;
+ }
+
public:
reference<ConfigTag> config;
MYSQL *connection;
@@ -349,21 +374,8 @@ class SQLConnection : public SQL::Provider
{
if (q[i] != '?')
res.push_back(q[i]);
- else
- {
- if (param < p.size())
- {
- std::string parm = p[param++];
- // In the worst case, each character may need to be encoded as using two bytes,
- // and one byte is the terminating null
- std::vector<char> buffer(parm.length() * 2 + 1);
-
- // The return value of mysql_real_escape_string() is the length of the encoded string,
- // not including the terminating null
- unsigned long escapedsize = mysql_real_escape_string(connection, &buffer[0], parm.c_str(), parm.length());
- res.append(&buffer[0], escapedsize);
- }
- }
+ else if (param < p.size() && !EscapeString(call, p[param++], res))
+ return;
}
Submit(call, res);
}
@@ -384,14 +396,8 @@ class SQLConnection : public SQL::Provider
i--;
SQL::ParamMap::const_iterator it = p.find(field);
- if (it != p.end())
- {
- std::string parm = it->second;
- // NOTE: See above
- std::vector<char> buffer(parm.length() * 2 + 1);
- unsigned long escapedsize = mysql_escape_string(&buffer[0], parm.c_str(), parm.length());
- res.append(&buffer[0], escapedsize);
- }
+ if (it != p.end() && !EscapeString(call, it->second, res))
+ return;
}
}
Submit(call, res);
@@ -405,6 +411,9 @@ ModuleSQL::ModuleSQL()
void ModuleSQL::init()
{
+ if (mysql_library_init(0, NULL, NULL))
+ throw ModuleException("Unable to initialise the MySQL library!");
+
Dispatcher = new DispatcherThread(this);
Dispatcher->Start();
}
@@ -417,10 +426,13 @@ ModuleSQL::~ModuleSQL()
Dispatcher->OnNotify();
delete Dispatcher;
}
+
for(ConnMap::iterator i = connections.begin(); i != connections.end(); i++)
{
delete i->second;
}
+
+ mysql_library_end();
}
void ModuleSQL::ReadConfig(ConfigStatus& status)