From dbebd7fbf44a8629bfc3a1b6ccc625aedf20ad17 Mon Sep 17 00:00:00 2001 From: tusooa Date: Wed, 28 Dec 2022 15:23:58 -0500 Subject: [PATCH] Validate language codes in MapOfString --- .../object_validators/map_of_string.ex | 20 ++++++++++++++++++- .../object_validators/map_of_string_test.exs | 12 +++++++++++ test/pleroma/multi_language_test.exs | 3 ++- 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/lib/pleroma/ecto_type/activity_pub/object_validators/map_of_string.ex b/lib/pleroma/ecto_type/activity_pub/object_validators/map_of_string.ex index 9c610a64b8..441c8c1813 100644 --- a/lib/pleroma/ecto_type/activity_pub/object_validators/map_of_string.ex +++ b/lib/pleroma/ecto_type/activity_pub/object_validators/map_of_string.ex @@ -12,7 +12,11 @@ def cast(object) when is_map(object) do object |> Enum.reduce(%{}, fn {lang, value}, acc when is_binary(lang) and is_binary(value) -> - Map.put(acc, lang, value) + if is_good_locale_code?(lang) do + Map.put(acc, lang, value) + else + acc + end _, acc -> acc @@ -21,6 +25,20 @@ def cast(object) when is_map(object) do {:ok, data} end + defp is_good_locale_code?(code) do + code + |> String.codepoints() + |> Enum.all?(&valid_char?/1) + end + + # [a-zA-Z0-9-] + defp valid_char?(char) do + ("a" <= char and char <= "z") or + ("A" <= char and char <= "Z") or + ("0" <= char and char <= "9") or + char == "-" + end + def cast(_), do: :error def dump(data), do: {:ok, data} diff --git a/test/pleroma/ecto_type/activity_pub/object_validators/map_of_string_test.exs b/test/pleroma/ecto_type/activity_pub/object_validators/map_of_string_test.exs index aecf482e3a..4ee179dc8e 100644 --- a/test/pleroma/ecto_type/activity_pub/object_validators/map_of_string_test.exs +++ b/test/pleroma/ecto_type/activity_pub/object_validators/map_of_string_test.exs @@ -35,6 +35,18 @@ test "it ignores non-strings within the map" do assert validated_data == %{"en-US" => "mew mew"} end + test "it ignores bad locale codes" do + data = %{ + "en-US" => "mew mew", + "en_GB" => "meow meow", + "en<<#@!$#!@%!GB" => "meow meow" + } + + assert {:ok, validated_data} = MapOfString.cast(data) + + assert validated_data == %{"en-US" => "mew mew"} + end + test "it complains with non-map data" do assert :error = MapOfString.cast("mew") assert :error = MapOfString.cast(["mew"]) diff --git a/test/pleroma/multi_language_test.exs b/test/pleroma/multi_language_test.exs index 15634d3707..aea25f1170 100644 --- a/test/pleroma/multi_language_test.exs +++ b/test/pleroma/multi_language_test.exs @@ -38,7 +38,8 @@ test "resistent to tampering" do "en-GB" => "meow {code} {content}" } - assert MultiLanguage.map_to_str(data) == "[en-GB] meow {code} {content} | [en-US] mew {code} {content}" + assert MultiLanguage.map_to_str(data) == + "[en-GB] meow {code} {content} | [en-US] mew {code} {content}" end end