Fix edge case of server tags unescaping, when the backslash is followed by an 'invalid' char.

This commit is contained in:
Valentin Lorentz 2020-05-01 23:46:34 +02:00
parent e92156711b
commit 01dcbf412b
2 changed files with 31 additions and 2 deletions

View File

@ -63,8 +63,19 @@ SERVER_TAG_ESCAPE = [
]
escape_server_tag_value = utils.str.MultipleReplacer(
dict(SERVER_TAG_ESCAPE))
unescape_server_tag_value = utils.str.MultipleReplacer(
dict(map(lambda x:(x[1],x[0]), SERVER_TAG_ESCAPE)))
_server_tag_unescape = {k: v for (v, k) in SERVER_TAG_ESCAPE}
_escape_sequence_pattern = re.compile(r'\\.?')
def _unescape_replacer(m):
escape_sequence = m.group(0)
unescaped = _server_tag_unescape.get(escape_sequence)
if unescaped is None:
# Matches both a lone \ at the end and a \ followed by an "invalid"
# character. In both cases, the \ must be dropped.
return escape_sequence[1:]
return unescaped
def unescape_server_tag_value(s):
return _escape_sequence_pattern.sub(_unescape_replacer, s)
def parse_server_tags(s):
server_tags = {}

View File

@ -163,6 +163,24 @@ class IrcMsgTestCase(SupyTestCase):
m._str = None # Clear the cache (set before parsing)
self.assertEqual(str(m), s + '\r\n')
# bar\1 is equivalent to baz1
s = r'@foo=;bar=baz\1;qux= ' \
r':nick!ident@host.com PRIVMSG me :Hello'
m = ircmsgs.IrcMsg(s)
self.assertEqual(m.server_tags, {
'foo': None,
'bar': 'baz1',
'qux': None})
# bar\ is equivalent to baz
s = r'@foo=;bar=baz\;qux= ' \
r':nick!ident@host.com PRIVMSG me :Hello'
m = ircmsgs.IrcMsg(s)
self.assertEqual(m.server_tags, {
'foo': None,
'bar': 'baz',
'qux': None})
s = r'@foo=;bar=baz;qux= ' \
r':nick!ident@host.com PRIVMSG me :Hello'
m = ircmsgs.IrcMsg(s)