mirror of
https://github.com/jlu5/PyLink.git
synced 2024-11-01 01:09:22 +01:00
Irc, clientbot: disallow unsetting bans that don't exist
This fixes an infinite loop when: - Clientbot modesync is enabled - 2 or more clientbot linked networks show unsetting modes that weren't enabled (e.g. charybdis) - A user removes a ban The workaround in clientbot prevents this process from triggering an infinite loop when a mode change acknowledgement is received for unsetting a non-existant ban, though multiple -b mode changes may still be seen due to race conditions in updating the various networks' states.
This commit is contained in:
parent
386c71475a
commit
72ca41df33
@ -601,7 +601,13 @@ class Irc():
|
||||
# Must have parameter.
|
||||
log.debug('Mode %s: This mode must have parameter.', mode)
|
||||
arg = args.pop(0)
|
||||
if prefix == '-' and mode in supported_modes['*B'] and arg == '*':
|
||||
if prefix == '-':
|
||||
log.debug('(%s) parseModes: checking if +%s %s is in old modes list: %s', self.name, mode, arg, oldmodes)
|
||||
if (mode, arg) not in oldmodes:
|
||||
# Ignore attempts to unset bans that don't exist.
|
||||
log.debug("(%s) parseModes(): ignoring removal of non-existent list mode +%s %s", self.name, mode, arg)
|
||||
continue
|
||||
elif prefix == '-' and mode in supported_modes['*B'] and arg == '*':
|
||||
# Charybdis allows unsetting +k without actually
|
||||
# knowing the key by faking the argument when unsetting
|
||||
# as a single "*".
|
||||
|
@ -184,7 +184,13 @@ class ClientbotWrapperProtocol(Protocol):
|
||||
"""Sends channel MODE changes."""
|
||||
if utils.isChannel(channel):
|
||||
extmodes = []
|
||||
for modepair in modes:
|
||||
# Re-parse all channel modes locally to eliminate anything invalid, such as unbanning
|
||||
# things that were never banned. This prevents the bot from getting caught in a loop
|
||||
# with IRCd MODE acknowledgements.
|
||||
# FIXME: More related safety checks should be added for this.
|
||||
log.debug('(%s) mode: re-parsing modes %s', self.irc.name, modes)
|
||||
joined_modes = self.irc.joinModes(modes)
|
||||
for modepair in self.irc.parseModes(channel, joined_modes):
|
||||
log.debug('(%s) mode: checking if %s a prefix mode: %s', self.irc.name, modepair, self.irc.prefixmodes)
|
||||
if modepair[0][-1] in self.irc.prefixmodes:
|
||||
if self.irc.isInternalClient(modepair[1]):
|
||||
@ -599,6 +605,7 @@ class ClientbotWrapperProtocol(Protocol):
|
||||
if self.irc.isInternalClient(target):
|
||||
log.debug('(%s) Suppressing MODE change hook for internal client %s', self.irc.name, target)
|
||||
return
|
||||
if changedmodes:
|
||||
return {'target': target, 'modes': changedmodes, 'channeldata': oldobj}
|
||||
|
||||
def handle_nick(self, source, command, args):
|
||||
|
Loading…
Reference in New Issue
Block a user