3
0
mirror of https://github.com/jlu5/PyLink.git synced 2024-11-27 21:19:31 +01:00

parse_modes: fix handling of +b-b ban cycles

This commit is contained in:
James Lu 2019-08-26 15:43:16 -07:00
parent c2b5966739
commit 9168880204
2 changed files with 33 additions and 3 deletions

View File

@ -952,13 +952,13 @@ class PyLinkNetworkCoreWithUtils(PyLinkNetworkCore):
arg = oldarg
log.debug("Mode %s: coersing argument of '*' to %r.", mode, arg)
log.debug('(%s) parse_modes: checking if +%s %s is in old modes list: %s', self.name, mode, arg, existing)
log.debug('(%s) parse_modes: checking if +%s %s is in old modes list: %s; existing_casemap=%s', self.name, mode, arg, existing, existing_casemap)
arg = self.to_lower(arg)
casefolded_modepair = existing_casemap.get((mode, arg)) # Case fold arguments as needed
if casefolded_modepair not in existing:
# Ignore attempts to unset parameter modes that don't exist.
log.debug("(%s) parse_modes(): ignoring removal of non-existent list mode +%s %s", self.name, mode, arg)
log.debug("(%s) parse_modes: ignoring removal of non-existent list mode +%s %s; casefolded_modepair=%s", self.name, mode, arg, casefolded_modepair)
continue
arg = casefolded_modepair[1]
@ -975,9 +975,16 @@ class PyLinkNetworkCoreWithUtils(PyLinkNetworkCore):
newmode = (prefix + mode, arg)
res.append(newmode)
# Tentatively apply the new mode to the "existing" mode list.
# Tentatively apply the new mode to the "existing" mode list. This is so queries
# like +b-b *!*@example.com *!*@example.com behave correctly
# (we can't rely on the original mode list to check whether a mode currently exists)
existing = self._apply_modes(existing, [newmode], is_channel=is_channel)
lowered_mode = (newmode[0][-1], self.to_lower(newmode[1]) if newmode[1] else newmode[1])
if prefix == '+' and lowered_mode not in existing_casemap:
existing_casemap[lowered_mode] = (mode, arg)
elif prefix == '-' and lowered_mode in existing_casemap:
del existing_casemap[lowered_mode]
return res
def parse_modes(self, target, args, ignore_missing_args=False):

View File

@ -390,6 +390,29 @@ class BaseProtocolTest(unittest.TestCase):
"Second ban should have been removed (different case)"
)
def test_parse_modes_channel_ban_cycle(self):
c = self.p.channels['#testruns'] = Channel(self.p, name='#testruns')
self.assertEqual(
self.p.parse_modes('#testruns', ['+b-b', '*!*@example.com', '*!*@example.com']),
[('+b', '*!*@example.com'), ('-b', '*!*@example.com')],
"Cycling a ban +b-b should remove it"
)
self.assertEqual(
self.p.parse_modes('#testruns', ['-b+b', '*!*@example.com', '*!*@example.com']),
[('+b', '*!*@example.com')],
"Cycling a ban -b+b should add it"
)
self.assertEqual(
self.p.parse_modes('#testruns', ['+b-b', '*!*@example.com', '*!*@Example.com']),
[('+b', '*!*@example.com'), ('-b', '*!*@example.com')],
"Cycling a ban +b-b should remove it (different case)"
)
self.assertEqual(
self.p.parse_modes('#testruns', ['+b-b', '*!*@Example.com', '*!*@example.com']),
[('+b', '*!*@Example.com'), ('-b', '*!*@Example.com')],
"Cycling a ban +b-b should remove it (different case)"
)
def test_parse_mode_channel_prefixmode_has_nick(self):
c = self.p.channels['#'] = Channel(self.p, name='#')
u = self._make_user('mynick', uid='myuid')