Skip to content

Commit 80dc1da

Browse files
committed
Fix crash when WHOISing invalid MXID
1 parent 8cf8f99 commit 80dc1da

File tree

2 files changed

+63
-41
lines changed

2 files changed

+63
-41
lines changed

lib/irc/handler.ex

Lines changed: 50 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1102,51 +1102,61 @@ defmodule M51.IrcConn.Handler do
11021102
[_server, target | _] -> target
11031103
end
11041104

1105-
[local_name, hostname] = String.split(target, ":", parts: 2)
1105+
case String.split(target, ":", parts: 2) do
1106+
[_] ->
1107+
# return ERR_NOSUCHNICK
1108+
if target == "" || String.contains?(target, " ") do
1109+
send_numeric.("401", ["*", "No such nick"])
1110+
else
1111+
send_numeric.("401", [target, "No such nick"])
1112+
end
11061113

1107-
[member: memberships] = M51.MatrixClient.State.user(matrix_state, target)
1114+
[local_name, hostname] ->
1115+
[member: memberships] = M51.MatrixClient.State.user(matrix_state, target)
11081116

1109-
# TODO: pick the most common display name instead
1110-
gecos = target
1117+
# TODO: pick the most common display name instead
1118+
gecos = target
11111119

1112-
overhead = make_numeric.("353", [target, ""]) |> M51.Irc.Command.format() |> byte_size()
1120+
overhead =
1121+
make_numeric.("353", [target, ""]) |> M51.Irc.Command.format() |> byte_size()
11131122

1114-
first_commands = [
1115-
# RPL_WHOISUSER "<nick> <username> <host> * :<realname>"
1116-
make_numeric.("311", [target, local_name, hostname, "*", gecos])
1117-
]
1123+
first_commands = [
1124+
# RPL_WHOISUSER "<nick> <username> <host> * :<realname>"
1125+
make_numeric.("311", [target, local_name, hostname, "*", gecos])
1126+
]
11181127

1119-
channel_commands =
1120-
memberships
1121-
|> Map.keys()
1122-
|> Enum.map(fn room_id ->
1123-
M51.MatrixClient.State.room_irc_channel(matrix_state, room_id)
1124-
end)
1125-
|> Enum.sort()
1126-
|> M51.Irc.WordWrap.join_tokens(512 - overhead)
1127-
|> Enum.map(fn line ->
1128-
line = line |> String.trim_trailing()
1129-
1130-
if line != "" do
1131-
# RPL_WHOISCHANNELS "<nick> :[prefix]<channel>{ [prefix]<channel>}"
1132-
make_numeric.("319", [target, line])
1133-
end
1134-
end)
1135-
|> Enum.filter(fn line -> line != nil end)
1136-
1137-
last_commands = [
1138-
# RPL_WHOISSERVER "<nick> <server> :<server info>"
1139-
make_numeric.("312", [target, hostname, hostname]),
1140-
# RPL_WHOISACCOUNT "<nick> <account> :is logged in as"
1141-
make_numeric.("330", [target, target, "is logged in as"]),
1142-
# RPL_ENDOFWHOIS
1143-
make_numeric.("318", [target, "End of WHOIS"])
1144-
]
1145-
1146-
send_batch.(
1147-
Enum.concat([first_commands, channel_commands, last_commands]),
1148-
"labeled-response"
1149-
)
1128+
channel_commands =
1129+
memberships
1130+
|> Map.keys()
1131+
|> Enum.map(fn room_id ->
1132+
M51.MatrixClient.State.room_irc_channel(matrix_state, room_id)
1133+
end)
1134+
|> Enum.sort()
1135+
|> M51.Irc.WordWrap.join_tokens(512 - overhead)
1136+
|> Enum.map(fn line ->
1137+
line = line |> String.trim_trailing()
1138+
1139+
if line != "" do
1140+
# RPL_WHOISCHANNELS "<nick> :[prefix]<channel>{ [prefix]<channel>}"
1141+
make_numeric.("319", [target, line])
1142+
end
1143+
end)
1144+
|> Enum.filter(fn line -> line != nil end)
1145+
1146+
last_commands = [
1147+
# RPL_WHOISSERVER "<nick> <server> :<server info>"
1148+
make_numeric.("312", [target, hostname, hostname]),
1149+
# RPL_WHOISACCOUNT "<nick> <account> :is logged in as"
1150+
make_numeric.("330", [target, target, "is logged in as"]),
1151+
# RPL_ENDOFWHOIS
1152+
make_numeric.("318", [target, "End of WHOIS"])
1153+
]
1154+
1155+
send_batch.(
1156+
Enum.concat([first_commands, channel_commands, last_commands]),
1157+
"labeled-response"
1158+
)
1159+
end
11501160

11511161
{"BATCH", [first_param | params]} ->
11521162
{first_char, reference_tag} = String.split_at(first_param, 1)

test/irc/handler_test.exs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -828,7 +828,7 @@ defmodule M51.IrcConn.HandlerTest do
828828
assert_line("BATCH :-#{batch_id}\r\n")
829829
end
830830

831-
test "WHOIS", %{handler: handler} do
831+
test "WHOIS unknown user", %{handler: handler} do
832832
do_connection_registration(handler)
833833

834834
send(handler, cmd("@label=l1 WHOIS unknown_user:example.com"))
@@ -855,6 +855,18 @@ defmodule M51.IrcConn.HandlerTest do
855855
assert_line("BATCH :-#{batch_id}\r\n")
856856
end
857857

858+
test "WHOIS non-MXID", %{handler: handler} do
859+
do_connection_registration(handler)
860+
861+
send(handler, cmd("@label=l1 WHOIS not_enough_colons"))
862+
863+
assert_line("@label=l1 :server. 401 foo:example.org not_enough_colons :No such nick\r\n")
864+
865+
send(handler, cmd("@label=l1 WHOIS :with spaces"))
866+
867+
assert_line("@label=l1 :server. 401 foo:example.org * :No such nick\r\n")
868+
end
869+
858870
test "MODE on user", %{handler: handler} do
859871
do_connection_registration(handler)
860872

0 commit comments

Comments
 (0)