diff options
author | Nicolas Hake <nh@nosebud.de> | 2016-06-30 11:31:19 +0200 |
---|---|---|
committer | Nicolas Hake <nh@nosebud.de> | 2016-11-07 16:33:46 +0100 |
commit | 7bebc148b23713e1c9842b14c978f58f2ae78bb6 (patch) | |
tree | dffccf9933069c862f6a587712e06ca7c2a4e6b7 /lib | |
parent | Add 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.ex | 34 |
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 |