From 393c1afdd7bfede2b7f489d7ceb000c909c0fccf Mon Sep 17 00:00:00 2001 From: brain Date: Thu, 25 Oct 2007 15:25:32 +0000 Subject: this should fix any of the crashes w00t outlined where User::MyClass == NULL. The simplest fix seems to be that if the user has no class, skip all the code that uses the class values. This makes sense because the only situation where User::MyClass == NULL is when they arent authorised to connect and are being quit so checking flood levels and max sendq etc are irrelevent. git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@8358 e03df62e-2008-0410-955e-edbf42e46eb7 --- src/command_parse.cpp | 33 +++++++++++++++++++-------------- src/userprocess.cpp | 31 +++++++++++++++++-------------- src/users.cpp | 8 ++++---- 3 files changed, 40 insertions(+), 32 deletions(-) (limited to 'src') diff --git a/src/command_parse.cpp b/src/command_parse.cpp index 9df7f4754..5492e26b5 100644 --- a/src/command_parse.cpp +++ b/src/command_parse.cpp @@ -223,22 +223,25 @@ void CommandParser::DoLines(User* current, bool one_only) while (current->BufferIsReady()) { - if (ServerInstance->Time() > current->reset_due) + if (current->MyClass) { - current->reset_due = ServerInstance->Time() + current->MyClass->GetThreshold(); - current->lines_in = 0; - } + if (ServerInstance->Time() > current->reset_due) + { + current->reset_due = ServerInstance->Time() + current->MyClass->GetThreshold(); + current->lines_in = 0; + } - if (++current->lines_in > current->MyClass->GetFlood() && current->MyClass->GetFlood()) - { - ServerInstance->FloodQuitUser(current); - return; - } + if (++current->lines_in > current->MyClass->GetFlood() && current->MyClass->GetFlood()) + { + ServerInstance->FloodQuitUser(current); + return; + } - if ((++floodlines > current->MyClass->GetFlood()) && (current->MyClass->GetFlood() != 0)) - { - ServerInstance->FloodQuitUser(current); - return; + if ((++floodlines > current->MyClass->GetFlood()) && (current->MyClass->GetFlood() != 0)) + { + ServerInstance->FloodQuitUser(current); + return; + } } // use GetBuffer to copy single lines into the sanitized string @@ -305,7 +308,9 @@ bool CommandParser::ProcessCommand(User *user, std::string &cmd) } /* activity resets the ping pending timer */ - user->nping = ServerInstance->Time() + user->MyClass->GetPingTime(); + if (user->MyClass) + user->nping = ServerInstance->Time() + user->MyClass->GetPingTime(); + if (cm->second->flags_needed) { if (!user->IsModeSet(cm->second->flags_needed)) diff --git a/src/userprocess.cpp b/src/userprocess.cpp index a3c8bc305..eb5ea050c 100644 --- a/src/userprocess.cpp +++ b/src/userprocess.cpp @@ -101,21 +101,24 @@ void ProcessUserHandler::Call(User* cu) // AddBuffer returned false, theres too much data in the user's buffer and theyre up to no good. if (current->registered == REG_ALL) { - // Make sure they arn't flooding long lines. - if (Server->Time() > current->reset_due) + if (current->MyClass) { - current->reset_due = Server->Time() + current->MyClass->GetThreshold(); - current->lines_in = 0; - } - - current->lines_in++; - - if (current->MyClass->GetFlood() && current->lines_in > current->MyClass->GetFlood()) - Server->FloodQuitUser(current); - else - { - current->WriteServ("NOTICE %s :Your previous line was too long and was not delivered (Over %d chars) Please shorten it.", current->nick, MAXBUF-2); - current->recvq.clear(); + // Make sure they arn't flooding long lines. + if (Server->Time() > current->reset_due) + { + current->reset_due = Server->Time() + current->MyClass->GetThreshold(); + current->lines_in = 0; + } + + current->lines_in++; + + if (current->MyClass->GetFlood() && current->lines_in > current->MyClass->GetFlood()) + Server->FloodQuitUser(current); + else + { + current->WriteServ("NOTICE %s :Your previous line was too long and was not delivered (Over %d chars) Please shorten it.", current->nick, MAXBUF-2); + current->recvq.clear(); + } } } else diff --git a/src/users.cpp b/src/users.cpp index 1affa67db..dbe179989 100644 --- a/src/users.cpp +++ b/src/users.cpp @@ -495,7 +495,7 @@ bool User::AddBuffer(std::string a) if (a.length()) recvq.append(a); - if (recvq.length() > (unsigned)this->MyClass->GetRecvqMax()) + if (this->MyClass && (recvq.length() > this->MyClass->GetRecvqMax())) { this->SetWriteError("RecvQ exceeded"); ServerInstance->WriteOpers("*** User %s RecvQ of %d exceeds connect class maximum of %d",this->nick,recvq.length(),this->MyClass->GetRecvqMax()); @@ -567,7 +567,7 @@ void User::AddWriteBuf(const std::string &data) if (*this->GetWriteError()) return; - if (sendq.length() + data.length() > (unsigned)this->MyClass->GetSendqMax()) + if (this->MyClass && (sendq.length() + data.length() > this->MyClass->GetSendqMax())) { /* * Fix by brain - Set the error text BEFORE calling writeopers, because @@ -933,12 +933,12 @@ void User::FullConnect() /* Check the password, if one is required by the user's connect class. * This CANNOT be in CheckClass(), because that is called prior to PASS as well! */ - if ((!this->MyClass->GetPass().empty()) && (!this->haspassed)) + if (this->MyClass && !this->MyClass->GetPass().empty() && !this->haspassed) { User::QuitUser(ServerInstance, this, "Invalid password"); return; } - + if (!this->exempt) { GLine* r = ServerInstance->XLines->matches_gline(this); -- cgit v1.2.3