summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorNicolas Hake <nh@nosebud.de>2016-06-30 11:31:19 +0200
committerNicolas Hake <nh@nosebud.de>2016-11-07 16:33:46 +0100
commit7bebc148b23713e1c9842b14c978f58f2ae78bb6 (patch)
treedffccf9933069c862f6a587712e06ca7c2a4e6b7 /lib
parentAdd tests for prefix handling (diff)
Stop over-eager splitting of message prefix
RFC2812 allows usernames to contain ! and . characters, which means parse_from used to split those up into multiple elements, thus failing the pattern match which expected the username to be a single string. Instead of prematurely splitting up the string, use a regexp that allows the username to contain any character but @.
Diffstat (limited to 'lib')
-rw-r--r--lib/exirc/utils.ex34
1 files changed, 12 insertions, 22 deletions
diff --git a/lib/exirc/utils.ex b/lib/exirc/utils.ex
index 41686ad..a5f18b5 100644
--- a/lib/exirc/utils.ex
+++ b/lib/exirc/utils.ex
@@ -25,23 +25,21 @@ defmodule ExIrc.Utils do
end
end
- @split_pattern ~r/(!|@|\.)/
+ @prefix_pattern ~r/^(?<nick>[^!]+)(?:(?:!(?<user>[^@ ]+))?(?:@(?<host>[\w.:-]+)))?$/
defp parse_from(from, msg) do
from_str = IO.iodata_to_binary(from)
- splits = Regex.scan(@split_pattern, from_str, return: :index)
- |> Enum.map(fn [{start, len},_] -> binary_part(from_str, start, len) end)
- parts = Regex.split(@split_pattern, from_str)
- woven = weave(splits, parts)
- case woven do
- [nick, "!", user, "@" | host] ->
- %{msg | nick: nick, user: user, host: Enum.join(host)}
- [nick, "@" | host] ->
- %{msg | nick: nick, host: Enum.join(host)}
- [_, "." | _] ->
- # from is probably a server name
- %{msg | server: to_string(from)}
+ parts = Regex.run(@prefix_pattern, from_str, capture: :all_but_first)
+ case parts do
+ [nick, user, host] ->
+ %{msg | nick: nick, user: user, host: host}
+ [nick, host] ->
+ %{msg | nick: nick, host: host}
[nick] ->
- %{msg | nick: nick}
+ if String.contains?(nick, ".") do
+ %{msg | server: nick}
+ else
+ %{msg | nick: nick}
+ end
end
end
@@ -180,12 +178,4 @@ defmodule ExIrc.Utils do
end
end
- defp weave(xs, ys) do
- do_weave(xs, ys, [])
- |> Enum.filter(fn "" -> false; _ -> true end)
- end
- defp do_weave([], ys, result), do: (ys ++ result) |> Enum.reverse
- defp do_weave(xs, [], result), do: (xs ++ result) |> Enum.reverse
- defp do_weave([hx|xs], [hy|ys], result), do: do_weave(xs, ys, [hx, hy | result])
-
end