From: Shane Synan Date: Thu, 29 Sep 2016 00:28:28 +0000 (-0500) Subject: Hide AutoWHO for nicks without IrcUser objects X-Git-Tag: travis-deploy-test~343 X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=commitdiff_plain;h=eabcc4905f991bb372cb2fb125b766802366701a;hp=27f186f9c78928d8c929d534f9f845978ba5bc83 Hide AutoWHO for nicks without IrcUser objects Don't require an IrcUser to exist when checking if WHO replies should be hidden. The nickname is enough for checking. This mimics CoreSessionEventProcessor::processIrcEvent403, where ERR_NOSUCHCHANNEL replies are hidden if nickname is in the list regardless of whether or not an IrcUser object exists. Potentially fixes AutoWHO replies showing in the server buffer when nicks quickly join and leave channels, resulting in the IrcUser object getting destroyed before the server replies to the AutoWHO request. It's difficult to recreate the issue on demand, so it's quite possible there's more to fix. Resolves GH-256. --- diff --git a/src/core/coresessioneventprocessor.cpp b/src/core/coresessioneventprocessor.cpp index c3e6cc10..e4621bf4 100644 --- a/src/core/coresessioneventprocessor.cpp +++ b/src/core/coresessioneventprocessor.cpp @@ -1008,16 +1008,24 @@ void CoreSessionEventProcessor::processIrcEvent352(IrcEvent *e) return; QString channel = e->params()[0]; - IrcUser *ircuser = e->network()->ircUser(e->params()[4]); + // Store the nick separate from ircuser for AutoWho check below + QString nick = e->params()[4]; + IrcUser *ircuser = e->network()->ircUser(nick); if (ircuser) { + // Only process the WHO information if an IRC user exists. Don't create an IRC user here; + // there's no way to track when the user quits, which would leave a phantom IrcUser lying + // around. + // NOTE: Whenever MONITOR support is introduced, the IrcUser will be created by an + // RPL_MONONLINE numeric before any WHO commands are run. processWhoInformation(e->network(), channel, ircuser, e->params()[3], e->params()[1], e->params()[2], e->params()[5], e->params().last().section(" ", 1)); } // Check if channel name has a who in progress. - // If not, then check if user nick exists and has a who in progress. + // If not, then check if user nickname has a who in progress. Use nick directly; don't use + // ircuser as that may be deleted (e.g. nick joins channel, leaves before WHO reply received). if (coreNetwork(e)->isAutoWhoInProgress(channel) || - (ircuser && coreNetwork(e)->isAutoWhoInProgress(ircuser->nick()))) { + (coreNetwork(e)->isAutoWhoInProgress(nick))) { e->setFlag(EventManager::Silent); } } @@ -1104,8 +1112,14 @@ void CoreSessionEventProcessor::processIrcEvent354(IrcEvent *e) return; QString channel = e->params()[1]; - IrcUser *ircuser = e->network()->ircUser(e->params()[5]); + QString nick = e->params()[5]; + IrcUser *ircuser = e->network()->ircUser(nick); if (ircuser) { + // Only process the WHO information if an IRC user exists. Don't create an IRC user here; + // there's no way to track when the user quits, which would leave a phantom IrcUser lying + // around. + // NOTE: Whenever MONITOR support is introduced, the IrcUser will be created by an + // RPL_MONONLINE numeric before any WHO commands are run. processWhoInformation(e->network(), channel, ircuser, e->params()[4], e->params()[2], e->params()[3], e->params()[6], e->params().last()); // Don't use .section(" ", 1) with WHOX replies, for there's no hopcount to trim out @@ -1123,9 +1137,10 @@ void CoreSessionEventProcessor::processIrcEvent354(IrcEvent *e) } // Check if channel name has a who in progress. - // If not, then check if user nick exists and has a who in progress. + // If not, then check if user nickname has a who in progress. Use nick directly; don't use + // ircuser as that may be deleted (e.g. nick joins channel, leaves before WHO reply received). if (coreNetwork(e)->isAutoWhoInProgress(channel) || - (ircuser && coreNetwork(e)->isAutoWhoInProgress(ircuser->nick()))) { + (coreNetwork(e)->isAutoWhoInProgress(nick))) { e->setFlag(EventManager::Silent); } }