|
19 | 19 | # talk to someone if they are in an active conversation with them. |
20 | 20 | LEFT_WHILE_TALKING_TIMEOUT = 60 * 10 |
21 | 21 |
|
| 22 | +# By RFC, only these characters are allowed in a nickname. |
| 23 | +REGEX_NICKNAME_FILTER = r"[^a-zA-Z0-9_\-\[\]\{\}\|]" |
| 24 | +# By RFC, a nickname cannot start with a number or a dash. |
| 25 | +REGEX_NICKNAME_START_FILTER = r"^[0-9\-]+" |
| 26 | +# By implementation, a username is more strict than a nickname in what |
| 27 | +# it can start with. This filter is in addition to the nickname filters. |
| 28 | +REGEX_USERNAME_START_FILTER = r"^[_\[\]\{\}\|]+" |
| 29 | + |
22 | 30 |
|
23 | 31 | class IRCRelay(irc.client_aio.AioSimpleIRCClient): |
24 | 32 | def __init__(self, host, port, nickname, channel, puppet_ip_range, puppet_postfix, ignore_list, idle_timeout): |
@@ -129,10 +137,8 @@ async def _pinger(self): |
129 | 137 |
|
130 | 138 | async def _connect(self): |
131 | 139 | while True: |
132 | | - username = self._nickname |
133 | | - # An additional constraints usernames have over nicknames, that they are |
134 | | - # also not allowed to start with an underscore. |
135 | | - username = re.sub(r"^_+", "", username) |
| 140 | + # Additional constraints usernames have over nicknames. |
| 141 | + username = re.sub(REGEX_USERNAME_START_FILTER, "", self._nickname) |
136 | 142 |
|
137 | 143 | try: |
138 | 144 | await self.connection.connect( |
@@ -168,11 +174,15 @@ async def _send_message(self, discord_id, discord_username, message, is_action=F |
168 | 174 | sanitized_discord_username = self._sanitize_discord_username(discord_username) |
169 | 175 | ipv6_address = self._puppet_ip_range[self._generate_ipv6_bits(sanitized_discord_username)] |
170 | 176 |
|
| 177 | + irc_nickname = f"{sanitized_discord_username}{self._puppet_postfix}" |
| 178 | + irc_username = re.sub(REGEX_USERNAME_START_FILTER, "", irc_nickname) |
| 179 | + |
171 | 180 | self._puppets[discord_id] = IRCPuppet( |
172 | 181 | self._host, |
173 | 182 | self._port, |
174 | 183 | ipv6_address, |
175 | | - f"{sanitized_discord_username}{self._puppet_postfix}", |
| 184 | + irc_nickname, |
| 185 | + irc_username, |
176 | 186 | self._channel, |
177 | 187 | functools.partial(self._remove_puppet, discord_id), |
178 | 188 | self._idle_timeout, |
@@ -211,10 +221,10 @@ def _sanitize_discord_username(self, discord_username): |
211 | 221 | original_discord_username = discord_username |
212 | 222 |
|
213 | 223 | discord_username = discord_username.strip() |
214 | | - # Remove all characters not allowed in IRC usernames. |
215 | | - discord_username = re.sub(r"[^a-zA-Z0-9_\-\[\]\{\}\|]", "", discord_username) |
216 | | - # Make sure a username doesn't start with a number or "-". |
217 | | - discord_username = re.sub(r"^[0-9\-]", "", discord_username) |
| 224 | + # Remove all characters not allowed in IRC nicknames. |
| 225 | + discord_username = re.sub(REGEX_NICKNAME_FILTER, "", discord_username) |
| 226 | + # Make sure a nicknames doesn't start with an invalid character. |
| 227 | + discord_username = re.sub(REGEX_NICKNAME_START_FILTER, "", discord_username) |
218 | 228 |
|
219 | 229 | # On Discord you can create usernames that don't contain any character valid |
220 | 230 | # on IRC, leaving an empty username. In that case we have no option but to |
|
0 commit comments