@@ -201,6 +201,9 @@ def build_chat_nickname_link(value: str, *, scheme_override: str | None = None)
201201 display = f"{ display } @{ server } "
202202 return ChatNicknameLink (href = href , title = title , display = display )
203203
204+ if not _IRC_NICK_RE .match (nick ):
205+ return None
206+
204207 href = f"irc://{ server } /{ nick } ,isnick"
205208 title = f"IRC on { server } "
206209 display = nick
@@ -209,37 +212,47 @@ def build_chat_nickname_link(value: str, *, scheme_override: str | None = None)
209212 return ChatNicknameLink (href = href , title = title , display = display )
210213
211214 if scheme == ChatScheme .matrix :
215+ localpart = nick .lstrip ("@" )
216+ if not _MATRIX_LOCALPART_RE .match (localpart ):
217+ return None
218+
212219 args = settings .CHAT_MATRIX_TO_ARGS
213220 args = args if isinstance (args , str ) and args else ""
214221
215- href = f"https://matrix.to/#/@{ nick } :{ server } "
222+ href = f"https://matrix.to/#/@{ localpart } :{ server } "
216223 if args :
217224 href = f"{ href } ?{ args } "
218225
219226 title = f"Matrix on { server } "
220227
221- display = f"@{ nick } "
228+ display = f"@{ localpart } "
222229 if not default_server or server != default_server :
223230 display = f"{ display } :{ server } "
224231
225232 return ChatNicknameLink (href = href , title = title , display = display , external = True )
226233
227234 if scheme == ChatScheme .mattermost :
235+ if not _SERVER_RE .match (server ) or not _MATTERMOST_USERNAME_RE .match (nick ):
236+ return None
237+
228238 if not team :
229239 # For default server we can fall back to the configured default team.
230240 if default_server and server == default_server and default_team :
231241 team = default_team
232242 else :
233243 return None
234244
245+ if not _MATTERMOST_TEAM_RE .match (team ):
246+ return None
247+
235248 href = f"https://{ server } /{ team } /messages/@{ nick } "
236249 title = f"Mattermost on { server } ({ team } )"
237250
238251 display = f"@{ nick } "
239252 if (default_server and server != default_server ) or (default_team and team != default_team ) or (not default_server ) or (not default_team ):
240253 display = f"@{ nick } :{ server } :{ team } "
241254
242- return ChatNicknameLink (href = href , title = title , display = display )
255+ return ChatNicknameLink (href = href , title = title , display = display , external = True )
243256
244257 return None
245258
@@ -405,6 +418,9 @@ def build_chat_channel_link(value: str, *, scheme_override: str | None = None) -
405418 if not channel or not server :
406419 return None
407420
421+ if not _SERVER_RE .match (server ) or not _MATTERMOST_CHANNEL_RE .match (channel ):
422+ return None
423+
408424 default_server = _get_default_server (ChatScheme .mattermost ) or ""
409425 default_team = _get_default_team () or ""
410426
@@ -414,14 +430,17 @@ def build_chat_channel_link(value: str, *, scheme_override: str | None = None) -
414430 else :
415431 return None
416432
433+ if not _MATTERMOST_TEAM_RE .match (team ):
434+ return None
435+
417436 href = f"https://{ server } /{ team } /channels/{ channel } "
418437 title = f"Mattermost channel on { server } ({ team } )"
419438
420439 display = f"~{ channel } "
421440 if (default_server and server != default_server ) or (default_team and team != default_team ) or (not default_server ) or (not default_team ):
422441 display = f"~{ channel } :{ server } :{ team } "
423442
424- return ChatChannelLink (href = href , title = title , display = display )
443+ return ChatChannelLink (href = href , title = title , display = display , external = True )
425444
426445 if not channel or not server :
427446 return None
0 commit comments