Emoji: Handle more edge cases for local emoji with strange filenames.

This commit is contained in:
Lain Soykaf 2026-01-06 15:12:49 +04:00 committed by Henry Jameson
commit 33b8ccf21f
6 changed files with 50 additions and 11 deletions

View file

@ -11,6 +11,8 @@ defmodule Pleroma.Emoji do
alias Pleroma.Emoji.Combinations
alias Pleroma.Emoji.Loader
alias Pleroma.Utils.URIEncoding
alias Pleroma.Web.Endpoint
require Logger
@ -189,8 +191,23 @@ defmodule Pleroma.Emoji do
def emoji_url(_), do: nil
@spec local_url(String.t() | nil) :: String.t() | nil
def local_url(nil), do: nil
def local_url("http" <> _ = url) do
URIEncoding.encode_url(url)
end
def local_url("/" <> _ = path) do
URIEncoding.encode_url(Endpoint.url() <> path, bypass_decode: true)
end
def local_url(path) when is_binary(path) do
local_url("/" <> path)
end
def build_emoji_tag({name, url}) do
url = URI.encode(url)
url = URIEncoding.encode_url(url)
%{
"icon" => %{"url" => "#{url}", "type" => "Image"},

View file

@ -5,7 +5,6 @@
defmodule Pleroma.Emoji.Formatter do
alias Pleroma.Emoji
alias Pleroma.HTML
alias Pleroma.Web.Endpoint
alias Pleroma.Web.MediaProxy
def emojify(text) do
@ -44,7 +43,7 @@ defmodule Pleroma.Emoji.Formatter do
Emoji.get_all()
|> Enum.filter(fn {emoji, %Emoji{}} -> String.contains?(text, ":#{emoji}:") end)
|> Enum.reduce(%{}, fn {name, %Emoji{file: file}}, acc ->
Map.put(acc, name, to_string(URI.merge(Endpoint.url(), file)))
Map.put(acc, name, Emoji.local_url(file))
end)
end

View file

@ -17,7 +17,6 @@ defmodule Pleroma.Web.ActivityPub.Builder do
alias Pleroma.Web.ActivityPub.Utils
alias Pleroma.Web.ActivityPub.Visibility
alias Pleroma.Web.CommonAPI.ActivityDraft
alias Pleroma.Web.Endpoint
require Pleroma.Constants
@ -105,7 +104,7 @@ defmodule Pleroma.Web.ActivityPub.Builder do
defp local_custom_emoji_react(data, emoji) do
with %{file: path} = emojo <- Emoji.get(emoji) do
url = "#{Endpoint.url()}#{path}"
url = Emoji.local_url(path)
add_emoji_content(data, emojo.code, url)
else
_ -> {:error, "Emoji does not exist"}

View file

@ -6,14 +6,13 @@ defmodule Pleroma.Web.MastodonAPI.CustomEmojiView do
use Pleroma.Web, :view
alias Pleroma.Emoji
alias Pleroma.Web.Endpoint
def render("index.json", %{custom_emojis: custom_emojis}) do
render_many(custom_emojis, __MODULE__, "show.json")
end
def render("show.json", %{custom_emoji: {shortcode, %Emoji{file: relative_url, tags: tags}}}) do
url = Endpoint.url() |> URI.merge(relative_url) |> to_string()
url = Emoji.local_url(relative_url)
%{
"shortcode" => shortcode,

View file

@ -7,7 +7,6 @@ defmodule Pleroma.Web.PleromaAPI.BookmarkFolderView do
alias Pleroma.BookmarkFolder
alias Pleroma.Emoji
alias Pleroma.Web.Endpoint
def render("show.json", %{folder: %BookmarkFolder{} = folder}) do
%{
@ -33,7 +32,7 @@ defmodule Pleroma.Web.PleromaAPI.BookmarkFolderView do
emoji = Emoji.get(emoji)
if emoji != nil do
Endpoint.url() |> URI.merge(emoji.file) |> to_string()
Emoji.local_url(emoji.file)
else
nil
end

View file

@ -1,8 +1,6 @@
defmodule Pleroma.Web.ActivityPub.Transmogrifier.EmojiTagBuildingTest do
use Pleroma.DataCase, async: true
alias Pleroma.Web.ActivityPub.Transmogrifier
test "it encodes the id to be a valid url" do
name = "hanapog"
url = "https://misskey.local.live/emojis/hana pog.png"
@ -11,4 +9,32 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.EmojiTagBuildingTest do
assert tag["id"] == "https://misskey.local.live/emojis/hana%20pog.png"
end
test "it does not double-encode already encoded urls" do
name = "hanapog"
url = "https://misskey.local.live/emojis/hana%20pog.png"
tag = Pleroma.Emoji.build_emoji_tag({name, url})
assert tag["id"] == url
end
test "it encodes disallowed path characters" do
name = "hanapog"
url = "https://example.com/emojis/hana[pog].png"
tag = Pleroma.Emoji.build_emoji_tag({name, url})
assert tag["id"] == "https://example.com/emojis/hana%5Bpog%5D.png"
end
test "local_url does not decode percent in filenames" do
url = Pleroma.Emoji.local_url("/emoji/hana%20pog.png")
assert url == Pleroma.Web.Endpoint.url() <> "/emoji/hana%2520pog.png"
tag = Pleroma.Emoji.build_emoji_tag({"hanapog", url})
assert tag["id"] == url
end
end