logo

pleroma

My custom branche(s) on git.pleroma.social/pleroma/pleroma git clone https://anongit.hacktivis.me/git/pleroma.git/
commit: 3ef98652f7b6613d543fa5b575e2f637cbb846c0
parent ee19d14b0619b04d75b980fa3235a397e372390d
Author: Lain Soykaf <lain@lain.com>
Date:   Wed,  7 Jan 2026 10:40:45 +0400

Emoji, AccountView, UtilController: Handle encoding of emoji

Diffstat:

Mlib/pleroma/emoji.ex3++-
Mlib/pleroma/web/mastodon_api/views/account_view.ex15++++++++++++++-
Mlib/pleroma/web/twitter_api/controllers/util_controller.ex11+++++++++++
Mtest/pleroma/web/activity_pub/transmogrifier/emoji_tag_building_test.exs6++++++
Mtest/pleroma/web/mastodon_api/views/account_view_test.exs19+++++++++++++++++++
5 files changed, 52 insertions(+), 2 deletions(-)

diff --git a/lib/pleroma/emoji.ex b/lib/pleroma/emoji.ex @@ -199,7 +199,8 @@ defmodule Pleroma.Emoji do end def local_url("/" <> _ = path) do - URIEncoding.encode_url(Endpoint.url() <> path, bypass_decode: true) + path = URIEncoding.encode_url(path, bypass_parse: true, bypass_decode: true) + Endpoint.url() <> path end def local_url(path) when is_binary(path) do diff --git a/lib/pleroma/web/mastodon_api/views/account_view.ex b/lib/pleroma/web/mastodon_api/views/account_view.ex @@ -9,6 +9,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do alias Pleroma.User alias Pleroma.UserNote alias Pleroma.UserRelationship + alias Pleroma.Utils.URIEncoding alias Pleroma.Web.CommonAPI.Utils alias Pleroma.Web.MastodonAPI.AccountView alias Pleroma.Web.MediaProxy @@ -238,7 +239,10 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do emojis = Enum.map(user.emoji, fn {shortcode, raw_url} -> - url = MediaProxy.url(raw_url) + url = + raw_url + |> encode_emoji_url() + |> MediaProxy.url() %{ shortcode: shortcode, @@ -511,4 +515,13 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do # See https://git.pleroma.social/pleroma/pleroma-meta/-/issues/14 user.actor_type == "Service" || user.actor_type == "Group" end + + defp encode_emoji_url(nil), do: nil + defp encode_emoji_url("http" <> _ = url), do: URIEncoding.encode_url(url) + + defp encode_emoji_url("/" <> _ = path), + do: URIEncoding.encode_url(path, bypass_parse: true, bypass_decode: true) + + defp encode_emoji_url(path) when is_binary(path), + do: URIEncoding.encode_url(path, bypass_parse: true, bypass_decode: true) end diff --git a/lib/pleroma/web/twitter_api/controllers/util_controller.ex b/lib/pleroma/web/twitter_api/controllers/util_controller.ex @@ -11,6 +11,7 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do alias Pleroma.Config alias Pleroma.Emoji alias Pleroma.Healthcheck + alias Pleroma.Utils.URIEncoding alias Pleroma.User alias Pleroma.Web.ActivityPub.ActivityPub alias Pleroma.Web.Auth.WrapperAuthenticator, as: Authenticator @@ -180,12 +181,22 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do def emoji(conn, _params) do emoji = Enum.reduce(Emoji.get_all(), %{}, fn {code, %Emoji{file: file, tags: tags}}, acc -> + file = encode_emoji_url(file) Map.put(acc, code, %{image_url: file, tags: tags}) end) json(conn, emoji) end + defp encode_emoji_url(nil), do: nil + defp encode_emoji_url("http" <> _ = url), do: URIEncoding.encode_url(url) + + defp encode_emoji_url("/" <> _ = path), + do: URIEncoding.encode_url(path, bypass_parse: true, bypass_decode: true) + + defp encode_emoji_url(path) when is_binary(path), + do: URIEncoding.encode_url(path, bypass_parse: true, bypass_decode: true) + def update_notification_settings(%{assigns: %{user: user}} = conn, params) do with {:ok, _} <- User.update_notification_settings(user, params) do json(conn, %{status: "success"}) diff --git a/test/pleroma/web/activity_pub/transmogrifier/emoji_tag_building_test.exs b/test/pleroma/web/activity_pub/transmogrifier/emoji_tag_building_test.exs @@ -37,4 +37,10 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.EmojiTagBuildingTest do assert tag["id"] == url end + + test "local_url encodes question marks in filenames" do + url = Pleroma.Emoji.local_url("/emoji/file?name.png") + + assert url == Pleroma.Web.Endpoint.url() <> "/emoji/file%3Fname.png" + end end diff --git a/test/pleroma/web/mastodon_api/views/account_view_test.exs b/test/pleroma/web/mastodon_api/views/account_view_test.exs @@ -105,6 +105,25 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do assert expected == AccountView.render("show.json", %{user: user, skip_visibility_check: true}) end + test "encodes emoji urls in the emojis field" do + user = + insert(:user, + name: ":brackets: :percent:", + emoji: %{ + "brackets" => "/emoji/hana[pog].png", + "percent" => "/emoji/hana%20pog.png" + } + ) + + %{emojis: emojis} = + AccountView.render("show.json", %{user: user, skip_visibility_check: true}) + + emoji_urls = Map.new(emojis, &{&1.shortcode, &1.url}) + + assert emoji_urls["brackets"] == "/emoji/hana%5Bpog%5D.png" + assert emoji_urls["percent"] == "/emoji/hana%2520pog.png" + end + describe "roles and privileges" do setup do clear_config([:instance, :moderator_privileges], [:cofe, :only_moderator])