mirror of
https://github.com/jlu5/PyLink.git
synced 2024-11-24 03:29:28 +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.
|
# Must have parameter.
|
||||||
log.debug('Mode %s: This mode must have parameter.', mode)
|
log.debug('Mode %s: This mode must have parameter.', mode)
|
||||||
arg = args.pop(0)
|
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
|
# Charybdis allows unsetting +k without actually
|
||||||
# knowing the key by faking the argument when unsetting
|
# knowing the key by faking the argument when unsetting
|
||||||
# as a single "*".
|
# as a single "*".
|
||||||
|
@ -184,7 +184,13 @@ class ClientbotWrapperProtocol(Protocol):
|
|||||||
"""Sends channel MODE changes."""
|
"""Sends channel MODE changes."""
|
||||||
if utils.isChannel(channel):
|
if utils.isChannel(channel):
|
||||||
extmodes = []
|
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)
|
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 modepair[0][-1] in self.irc.prefixmodes:
|
||||||
if self.irc.isInternalClient(modepair[1]):
|
if self.irc.isInternalClient(modepair[1]):
|
||||||
@ -599,7 +605,8 @@ class ClientbotWrapperProtocol(Protocol):
|
|||||||
if self.irc.isInternalClient(target):
|
if self.irc.isInternalClient(target):
|
||||||
log.debug('(%s) Suppressing MODE change hook for internal client %s', self.irc.name, target)
|
log.debug('(%s) Suppressing MODE change hook for internal client %s', self.irc.name, target)
|
||||||
return
|
return
|
||||||
return {'target': target, 'modes': changedmodes, 'channeldata': oldobj}
|
if changedmodes:
|
||||||
|
return {'target': target, 'modes': changedmodes, 'channeldata': oldobj}
|
||||||
|
|
||||||
def handle_nick(self, source, command, args):
|
def handle_nick(self, source, command, args):
|
||||||
"""Handles NICK changes."""
|
"""Handles NICK changes."""
|
||||||
|
Loading…
Reference in New Issue
Block a user