From d067eaa7b3bb76e7fc5ae019d6e00510b657171d Mon Sep 17 00:00:00 2001 From: rinpatch Date: Wed, 8 Apr 2020 22:58:31 +0300 Subject: [PATCH] formatter.ex: Use Phoenix.HTML for mention/hashtag generation Unlike concatenating strings, this makes sure everything is escaped. Tests had to be changed because Phoenix.HTML runs attributes through Enum.sort before generation for whatever reason. --- lib/pleroma/formatter.ex | 26 ++++++++++++++++--- test/formatter_test.exs | 24 +++++++---------- test/user_test.exs | 2 +- test/web/common_api/common_api_utils_test.exs | 6 ++--- .../update_credentials_test.exs | 4 +-- .../notification_controller_test.exs | 4 +-- test/web/twitter_api/twitter_api_test.exs | 2 +- 7 files changed, 41 insertions(+), 27 deletions(-) diff --git a/lib/pleroma/formatter.ex b/lib/pleroma/formatter.ex index e2a658cb3..c44e7fc8b 100644 --- a/lib/pleroma/formatter.ex +++ b/lib/pleroma/formatter.ex @@ -35,9 +35,19 @@ def mention_handler("@" <> nickname, buffer, opts, acc) do nickname_text = get_nickname_text(nickname, opts) link = - ~s(@#{ - nickname_text - }) + Phoenix.HTML.Tag.content_tag( + :span, + Phoenix.HTML.Tag.content_tag( + :a, + ["@", Phoenix.HTML.Tag.content_tag(:span, nickname_text)], + "data-user": id, + class: "u-url mention", + href: ap_id, + rel: "ugc" + ), + class: "h-card" + ) + |> Phoenix.HTML.safe_to_string() {link, %{acc | mentions: MapSet.put(acc.mentions, {"@" <> nickname, user})}} @@ -49,7 +59,15 @@ def mention_handler("@" <> nickname, buffer, opts, acc) do def hashtag_handler("#" <> tag = tag_text, _buffer, _opts, acc) do tag = String.downcase(tag) url = "#{Pleroma.Web.base_url()}/tag/#{tag}" - link = ~s(#{tag_text}) + + link = + Phoenix.HTML.Tag.content_tag(:a, tag_text, + class: "hashtag", + "data-tag": tag, + href: url, + rel: "tag ugc" + ) + |> Phoenix.HTML.safe_to_string() {link, %{acc | tags: MapSet.put(acc.tags, {tag_text, tag})}} end diff --git a/test/formatter_test.exs b/test/formatter_test.exs index cf8441cf6..93fd8eab7 100644 --- a/test/formatter_test.exs +++ b/test/formatter_test.exs @@ -150,13 +150,13 @@ test "gives a replacement for user links, using local nicknames in user links te assert length(mentions) == 3 expected_text = - ~s(@gsimg According to @gsimg According to @archa_eme_, that is @daggsy. Also hello @archa_eme_, that is @daggsy. Also hello @archaeme) + }" href="#{archaeme_remote.ap_id}" rel="ugc">@archaeme) assert expected_text == text end @@ -171,7 +171,7 @@ test "gives a replacement for user links when the user is using Osada" do assert length(mentions) == 1 expected_text = - ~s(@mike test) @@ -187,7 +187,7 @@ test "gives a replacement for single-character local nicknames" do assert length(mentions) == 1 expected_text = - ~s(@o hi) + ~s(@o hi) assert expected_text == text end @@ -209,17 +209,13 @@ test "given the 'safe_mention' option, it will only mention people in the beginn assert mentions == [{"@#{user.nickname}", user}, {"@#{other_user.nickname}", other_user}] assert expected_text == - ~s(@#{user.nickname} @#{user.nickname} @#{ - other_user.nickname - } hey dudes i hate @#{other_user.nickname} hey dudes i hate @#{ - third_user.nickname - }) + }" href="#{third_user.ap_id}" rel="ugc">@#{third_user.nickname}) end test "given the 'safe_mention' option, it will still work without any mention" do diff --git a/test/user_test.exs b/test/user_test.exs index 0479f294d..d39787f35 100644 --- a/test/user_test.exs +++ b/test/user_test.exs @@ -1404,7 +1404,7 @@ test "preserves hosts in user links text" do bio = "A.k.a. @nick@domain.com" expected_text = - ~s(A.k.a. @nick@domain.com) diff --git a/test/web/common_api/common_api_utils_test.exs b/test/web/common_api/common_api_utils_test.exs index d383d1714..98cf02d49 100644 --- a/test/web/common_api/common_api_utils_test.exs +++ b/test/web/common_api/common_api_utils_test.exs @@ -159,11 +159,11 @@ test "works for text/markdown with mentions" do {output, _, _} = Utils.format_input(text, "text/markdown") assert output == - ~s(

hello world

another @user__test and @user__test and @user__test google.com paragraph

) + }" href="http://foo.com/user__test" rel="ugc">@user__test google.com paragraph

) end end diff --git a/test/web/mastodon_api/controllers/account_controller/update_credentials_test.exs b/test/web/mastodon_api/controllers/account_controller/update_credentials_test.exs index d78fbc5a1..2d256f63c 100644 --- a/test/web/mastodon_api/controllers/account_controller/update_credentials_test.exs +++ b/test/web/mastodon_api/controllers/account_controller/update_credentials_test.exs @@ -82,9 +82,9 @@ test "updates the user's bio", %{conn: conn} do assert user_data = json_response(conn, 200) assert user_data["note"] == - ~s(I drink #cofe with #cofe with @#{user2.nickname}

suya..) + }" href="#{user2.ap_id}" rel="ugc">@#{user2.nickname}


suya..) end test "updates the user's locking status", %{conn: conn} do diff --git a/test/web/mastodon_api/controllers/notification_controller_test.exs b/test/web/mastodon_api/controllers/notification_controller_test.exs index 344eabb4a..6f1fab069 100644 --- a/test/web/mastodon_api/controllers/notification_controller_test.exs +++ b/test/web/mastodon_api/controllers/notification_controller_test.exs @@ -26,7 +26,7 @@ test "list of notifications" do |> get("/api/v1/notifications") expected_response = - "hi @#{user.nickname}" @@ -45,7 +45,7 @@ test "getting a single notification" do conn = get(conn, "/api/v1/notifications/#{notification.id}") expected_response = - "hi @#{user.nickname}" diff --git a/test/web/twitter_api/twitter_api_test.exs b/test/web/twitter_api/twitter_api_test.exs index 92f9aa0f5..f6e13b661 100644 --- a/test/web/twitter_api/twitter_api_test.exs +++ b/test/web/twitter_api/twitter_api_test.exs @@ -109,7 +109,7 @@ test "it registers a new user and parses mentions in the bio" do {:ok, user2} = TwitterAPI.register_user(data2) expected_text = - ~s(@john test)