From fcc4355c4b80e6598aa93dc7f8f40f80e979582c Mon Sep 17 00:00:00 2001 From: brain Date: Sat, 22 Jul 2006 13:30:34 +0000 Subject: I hate the fucking mysql devs. Craq smoking bastards. Upon Insert, number of rows is the number of rows effected but the number of columns is 0????? Add check to MySQLreply::Rows() to ensure the user doesnt see N rows and 0 columns! git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@4510 e03df62e-2008-0410-955e-edbf42e46eb7 --- src/modules/extra/m_mysql.cpp | 16 +++++--- src/modules/extra/m_sqllog.cpp | 86 +++++++++++++++++++++++++++++++----------- 2 files changed, 74 insertions(+), 28 deletions(-) diff --git a/src/modules/extra/m_mysql.cpp b/src/modules/extra/m_mysql.cpp index acfdf8214..38c3b4c93 100644 --- a/src/modules/extra/m_mysql.cpp +++ b/src/modules/extra/m_mysql.cpp @@ -254,16 +254,14 @@ class MySQLresult : public SQLresult } rows++; } - cols = field_count; mysql_free_result(res); } - log(DEBUG, "Created new MySQL result; %d rows, %d columns", rows, cols); + log(DEBUG, "Created new MySQL result; %d rows, %d columns", rows, colnames.size()); } MySQLresult(Module* self, Module* to, SQLerror e, unsigned int id) : SQLresult(self, to, id), currentrow(0) { rows = 0; - cols = 0; error = e; log(DEBUG,"Created new MySQLresult of error type"); } @@ -274,12 +272,18 @@ class MySQLresult : public SQLresult virtual int Rows() { - return rows; + /* An INSERT can return 0 columns, but N rows. This is unsafe to + * allow the user to 'see'. Go figure. I hate you, MySQL devs. + */ + if (colnames.size()) + return rows; + else + return 0; } virtual int Cols() { - return cols; + return colnames.size(); } virtual std::string ColName(int column) @@ -308,7 +312,7 @@ class MySQLresult : public SQLresult virtual SQLfield GetValue(int row, int column) { - if ((row >= 0) && (row < rows) && (column >= 0) && (column < cols)) + if ((row >= 0) && (row < rows) && (column >= 0) && (column < Cols())) { return fieldlists[row][column]; } diff --git a/src/modules/extra/m_sqllog.cpp b/src/modules/extra/m_sqllog.cpp index b8bdd57fa..add188c8c 100644 --- a/src/modules/extra/m_sqllog.cpp +++ b/src/modules/extra/m_sqllog.cpp @@ -60,6 +60,7 @@ class QueryInfo int hostid; int category; time_t date; + std::string lastquery; QueryInfo(const std::string &n, const std::string &h, unsigned long i, int cat) { @@ -70,6 +71,7 @@ class QueryInfo category = cat; sourceid = nickid = hostid = -1; date = TIME; + lastquery = ""; } void Go(SQLresult* res) @@ -86,26 +88,39 @@ class QueryInfo // If we find it, advance to FIND_NICK state, otherwise go to INSERT_SOURCE if (res->Rows()) { - qs = INSERT_SOURCE; + if (sourceid == -1) + { + sourceid = atoi(res->GetValue(0,0).d.c_str()); + qs = FIND_NICK; + } + else qs = INSERT_SOURCE; } else { - req = SQLreq(MyMod, SQLModule, dbid, "SELECT id,actor FROM ircd_log_actors WHERE actor='?'", nick); - if(req.Send()) + if (lastquery == "SELECT id,actor FROM ircd_log_actors WHERE actor='?'") { - qs = FIND_SOURCE; - active_queries[req.id] = this; + qs = INSERT_SOURCE; } else { - log(DEBUG, "SQLrequest failed: %s", req.error.Str()); + lastquery = "SELECT id,actor FROM ircd_log_actors WHERE actor='?'"; + req = SQLreq(MyMod, SQLModule, dbid, "SELECT id,actor FROM ircd_log_actors WHERE actor='?'", nick); + if(req.Send()) + { + qs = FIND_SOURCE; + active_queries[req.id] = this; + } + else + { + log(DEBUG, "SQLrequest failed: %s", req.error.Str()); + } + break; } - break; - } case INSERT_SOURCE: // "INSERT INTO ircd_log_actors VALUES('','"+nick+"')") // after we've done this, go back to FIND_SOURCE + lastquery = "INSERT INTO ircd_log_actors VALUES('','?')"; req = SQLreq(MyMod, SQLModule, dbid, "INSERT INTO ircd_log_actors VALUES('','?')", nick); if(req.Send()) { @@ -123,21 +138,33 @@ class QueryInfo // If we find it, advance to FIND_HOST state, otherwise go to INSERT_NICK if (res->Rows()) { - qs = INSERT_NICK; + if (nickid == -1) + { + nickid = atoi(res->GetValue(0,0).d.c_str()); + qs = FIND_HOST; + } + else qs = INSERT_NICK; } else { - req = SQLreq(MyMod, SQLModule, dbid, "SELECT id,actor FROM ircd_log_actors WHERE actor='?'", nick); - if(req.Send()) + if (lastquery == "SELECT id,actor FROM ircd_log_actors WHERE actor='?'") { - qs = FIND_NICK; - active_queries[req.id] = this; + qs = INSERT_NICK; } else { - log(DEBUG, "SQLrequest failed: %s", req.error.Str()); + req = SQLreq(MyMod, SQLModule, dbid, "SELECT id,actor FROM ircd_log_actors WHERE actor='?'", nick); + if(req.Send()) + { + qs = FIND_NICK; + active_queries[req.id] = this; + } + else + { + log(DEBUG, "SQLrequest failed: %s", req.error.Str()); + } + break; } - break; } case INSERT_NICK: // "INSERT INTO ircd_log_actors VALUES('','"+nick+"')") @@ -158,25 +185,39 @@ class QueryInfo // If we find it, advance to INSERT_LOGENTRY state, otherwise go to INSERT_HOST if (res->Rows()) { - qs = INSERT_HOST; + if (hostid == -1) + { + hostid = atoi(res->GetValue(0,0).d.c_str()); + qs = INSERT_LOGENTRY; + } + else qs = INSERT_HOST; } else { - req = SQLreq(MyMod, SQLModule, dbid, "SELECT id,hostname FROM ircd_log_hosts WHERE hostname='?'",hostname); - if(req.Send()) + if (lastquery == "SELECT id,hostname FROM ircd_log_hosts WHERE hostname='?'") { - qs = FIND_HOST; - active_queries[req.id] = this; + qs = INSERT_HOST; } else { - log(DEBUG, "SQLrequest failed: %s", req.error.Str()); + lastquery = "SELECT id,hostname FROM ircd_log_hosts WHERE hostname='?'"; + req = SQLreq(MyMod, SQLModule, dbid, "SELECT id,hostname FROM ircd_log_hosts WHERE hostname='?'",hostname); + if(req.Send()) + { + qs = FIND_HOST; + active_queries[req.id] = this; + } + else + { + log(DEBUG, "SQLrequest failed: %s", req.error.Str()); + } + break; } - break; } case INSERT_HOST: // "INSERT INTO ircd_log_hosts VALUES('','"+host+"')" // after we've done this, go back to FIND_HOST + lastquery = "INSERT INTO ircd_log_hosts VALUES('','?')"; req = SQLreq(MyMod, SQLModule, dbid, "INSERT INTO ircd_log_hosts VALUES('','?')", hostname); if(req.Send()) { @@ -198,6 +239,7 @@ class QueryInfo } else { + lastquery = "INSERT INTO ircd_log VALUES()"; req = SQLreq(MyMod, SQLModule, dbid, "INSERT INTO ircd_log VALUES('',"+ConvToStr(category)+","+ConvToStr(nickid)+","+ConvToStr(hostid)+","+ConvToStr(sourceid)+","+ConvToStr(date)+")"); /*,category, nickid, -- cgit v1.2.3