mirror of
https://git.pleroma.social/pleroma/pleroma.git
synced 2025-04-26 04:34:46 +00:00
StealEmojiPolicy: Sanitise emoji names.
This commit is contained in:
parent
c143653364
commit
577b7cb061
2 changed files with 136 additions and 11 deletions
|
@ -20,6 +20,19 @@ defmodule Pleroma.Web.ActivityPub.MRF.StealEmojiPolicy do
|
||||||
String.match?(shortcode, pattern)
|
String.match?(shortcode, pattern)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp reject_emoji?({shortcode, _url}, installed_emoji) do
|
||||||
|
valid_shortcode? = String.match?(shortcode, ~r/^[a-zA-Z0-9_-]+$/)
|
||||||
|
|
||||||
|
rejected_shortcode? =
|
||||||
|
[:mrf_steal_emoji, :rejected_shortcodes]
|
||||||
|
|> Config.get([])
|
||||||
|
|> Enum.any?(fn pattern -> shortcode_matches?(shortcode, pattern) end)
|
||||||
|
|
||||||
|
emoji_installed? = Enum.member?(installed_emoji, shortcode)
|
||||||
|
|
||||||
|
!valid_shortcode? or rejected_shortcode? or emoji_installed?
|
||||||
|
end
|
||||||
|
|
||||||
defp steal_emoji({shortcode, url}, emoji_dir_path) do
|
defp steal_emoji({shortcode, url}, emoji_dir_path) do
|
||||||
url = Pleroma.Web.MediaProxy.url(url)
|
url = Pleroma.Web.MediaProxy.url(url)
|
||||||
|
|
||||||
|
@ -78,16 +91,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.StealEmojiPolicy do
|
||||||
|
|
||||||
new_emojis =
|
new_emojis =
|
||||||
foreign_emojis
|
foreign_emojis
|
||||||
|> Enum.reject(fn {shortcode, _url} -> shortcode in installed_emoji end)
|
|> Enum.reject(&reject_emoji?(&1, installed_emoji))
|
||||||
|> Enum.reject(fn {shortcode, _url} -> String.contains?(shortcode, ["/", "\\"]) end)
|
|
||||||
|> Enum.filter(fn {shortcode, _url} ->
|
|
||||||
reject_emoji? =
|
|
||||||
[:mrf_steal_emoji, :rejected_shortcodes]
|
|
||||||
|> Config.get([])
|
|
||||||
|> Enum.find(false, fn pattern -> shortcode_matches?(shortcode, pattern) end)
|
|
||||||
|
|
||||||
!reject_emoji?
|
|
||||||
end)
|
|
||||||
|> Enum.map(&steal_emoji(&1, emoji_dir_path))
|
|> Enum.map(&steal_emoji(&1, emoji_dir_path))
|
||||||
|> Enum.filter(& &1)
|
|> Enum.filter(& &1)
|
||||||
|
|
||||||
|
|
|
@ -87,7 +87,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.StealEmojiPolicyTest do
|
||||||
assert File.exists?(fullpath)
|
assert File.exists?(fullpath)
|
||||||
end
|
end
|
||||||
|
|
||||||
test "rejects invalid shortcodes", %{path: path} do
|
test "rejects invalid shortcodes with slashes", %{path: path} do
|
||||||
message = %{
|
message = %{
|
||||||
"type" => "Create",
|
"type" => "Create",
|
||||||
"object" => %{
|
"object" => %{
|
||||||
|
@ -113,6 +113,58 @@ defmodule Pleroma.Web.ActivityPub.MRF.StealEmojiPolicyTest do
|
||||||
refute File.exists?(fullpath)
|
refute File.exists?(fullpath)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "rejects invalid shortcodes with dots", %{path: path} do
|
||||||
|
message = %{
|
||||||
|
"type" => "Create",
|
||||||
|
"object" => %{
|
||||||
|
"emoji" => [{"fired.fox", "https://example.org/emoji/firedfox"}],
|
||||||
|
"actor" => "https://example.org/users/admin"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fullpath = Path.join(path, "fired.fox.png")
|
||||||
|
|
||||||
|
Tesla.Mock.mock(fn %{method: :get, url: "https://example.org/emoji/firedfox"} ->
|
||||||
|
%Tesla.Env{status: 200, body: File.read!("test/fixtures/image.jpg")}
|
||||||
|
end)
|
||||||
|
|
||||||
|
clear_config(:mrf_steal_emoji, hosts: ["example.org"], size_limit: 284_468)
|
||||||
|
|
||||||
|
refute "fired.fox" in installed()
|
||||||
|
refute File.exists?(path)
|
||||||
|
|
||||||
|
assert {:ok, _message} = StealEmojiPolicy.filter(message)
|
||||||
|
|
||||||
|
refute "fired.fox" in installed()
|
||||||
|
refute File.exists?(fullpath)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "rejects invalid shortcodes with special characters", %{path: path} do
|
||||||
|
message = %{
|
||||||
|
"type" => "Create",
|
||||||
|
"object" => %{
|
||||||
|
"emoji" => [{"fired:fox", "https://example.org/emoji/firedfox"}],
|
||||||
|
"actor" => "https://example.org/users/admin"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fullpath = Path.join(path, "fired:fox.png")
|
||||||
|
|
||||||
|
Tesla.Mock.mock(fn %{method: :get, url: "https://example.org/emoji/firedfox"} ->
|
||||||
|
%Tesla.Env{status: 200, body: File.read!("test/fixtures/image.jpg")}
|
||||||
|
end)
|
||||||
|
|
||||||
|
clear_config(:mrf_steal_emoji, hosts: ["example.org"], size_limit: 284_468)
|
||||||
|
|
||||||
|
refute "fired:fox" in installed()
|
||||||
|
refute File.exists?(path)
|
||||||
|
|
||||||
|
assert {:ok, _message} = StealEmojiPolicy.filter(message)
|
||||||
|
|
||||||
|
refute "fired:fox" in installed()
|
||||||
|
refute File.exists?(fullpath)
|
||||||
|
end
|
||||||
|
|
||||||
test "reject regex shortcode", %{message: message} do
|
test "reject regex shortcode", %{message: message} do
|
||||||
refute "firedfox" in installed()
|
refute "firedfox" in installed()
|
||||||
|
|
||||||
|
@ -171,5 +223,74 @@ defmodule Pleroma.Web.ActivityPub.MRF.StealEmojiPolicyTest do
|
||||||
refute "firedfox" in installed()
|
refute "firedfox" in installed()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "accepts valid alphanum shortcodes", %{path: path} do
|
||||||
|
message = %{
|
||||||
|
"type" => "Create",
|
||||||
|
"object" => %{
|
||||||
|
"emoji" => [{"fire1fox", "https://example.org/emoji/fire1fox.png"}],
|
||||||
|
"actor" => "https://example.org/users/admin"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Tesla.Mock.mock(fn %{method: :get, url: "https://example.org/emoji/fire1fox.png"} ->
|
||||||
|
%Tesla.Env{status: 200, body: File.read!("test/fixtures/image.jpg")}
|
||||||
|
end)
|
||||||
|
|
||||||
|
clear_config(:mrf_steal_emoji, hosts: ["example.org"], size_limit: 284_468)
|
||||||
|
|
||||||
|
refute "fire1fox" in installed()
|
||||||
|
refute File.exists?(path)
|
||||||
|
|
||||||
|
assert {:ok, _message} = StealEmojiPolicy.filter(message)
|
||||||
|
|
||||||
|
assert "fire1fox" in installed()
|
||||||
|
end
|
||||||
|
|
||||||
|
test "accepts valid shortcodes with underscores", %{path: path} do
|
||||||
|
message = %{
|
||||||
|
"type" => "Create",
|
||||||
|
"object" => %{
|
||||||
|
"emoji" => [{"fire_fox", "https://example.org/emoji/fire_fox.png"}],
|
||||||
|
"actor" => "https://example.org/users/admin"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Tesla.Mock.mock(fn %{method: :get, url: "https://example.org/emoji/fire_fox.png"} ->
|
||||||
|
%Tesla.Env{status: 200, body: File.read!("test/fixtures/image.jpg")}
|
||||||
|
end)
|
||||||
|
|
||||||
|
clear_config(:mrf_steal_emoji, hosts: ["example.org"], size_limit: 284_468)
|
||||||
|
|
||||||
|
refute "fire_fox" in installed()
|
||||||
|
refute File.exists?(path)
|
||||||
|
|
||||||
|
assert {:ok, _message} = StealEmojiPolicy.filter(message)
|
||||||
|
|
||||||
|
assert "fire_fox" in installed()
|
||||||
|
end
|
||||||
|
|
||||||
|
test "accepts valid shortcodes with hyphens", %{path: path} do
|
||||||
|
message = %{
|
||||||
|
"type" => "Create",
|
||||||
|
"object" => %{
|
||||||
|
"emoji" => [{"fire-fox", "https://example.org/emoji/fire-fox.png"}],
|
||||||
|
"actor" => "https://example.org/users/admin"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Tesla.Mock.mock(fn %{method: :get, url: "https://example.org/emoji/fire-fox.png"} ->
|
||||||
|
%Tesla.Env{status: 200, body: File.read!("test/fixtures/image.jpg")}
|
||||||
|
end)
|
||||||
|
|
||||||
|
clear_config(:mrf_steal_emoji, hosts: ["example.org"], size_limit: 284_468)
|
||||||
|
|
||||||
|
refute "fire-fox" in installed()
|
||||||
|
refute File.exists?(path)
|
||||||
|
|
||||||
|
assert {:ok, _message} = StealEmojiPolicy.filter(message)
|
||||||
|
|
||||||
|
assert "fire-fox" in installed()
|
||||||
|
end
|
||||||
|
|
||||||
defp installed, do: Emoji.get_all() |> Enum.map(fn {k, _} -> k end)
|
defp installed, do: Emoji.get_all() |> Enum.map(fn {k, _} -> k end)
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue