fix(formatter): percent-encode quotes in Markdown URLs instead of cutting

Cutting the URL at the first quote dropped the rest of valid links such
as ?q=&quot;cat&quot;&page=2. Percent-encoding ", < and > keeps the URL
complete and still keeps it inside the attribute.
This commit is contained in:
Lain Soykaf 2026-10-22 16:28:06 +04:00
commit 58d4f6aa2c
No known key found for this signature in database
3 changed files with 19 additions and 11 deletions

View file

@ -388,10 +388,9 @@ defmodule Pleroma.FormatterTest do
test "escapes link attribute values" do
markdown = ~s|[click](http://example.com/?a=x" onerror="alert(1))|
html = Formatter.markdown_to_html(markdown)
assert html =~ ~s|href="http://example.com/?a=x"|
refute html =~ "onerror"
# The quotes are percent-encoded, so everything stays inside href.
assert Formatter.markdown_to_html(markdown) ==
~s|<p><a href="http://example.com/?a=x%22 onerror=%22alert(1)">click</a></p>|
end
test "preserves entities without rendering dangerous raw HTML" do
@ -416,10 +415,15 @@ defmodule Pleroma.FormatterTest do
test "rejects entity-encoded URL delimiters" do
markdown = "[click](http://example.com/?a=x&#34;onerror=alert(1))"
html = Formatter.markdown_to_html(markdown)
assert Formatter.markdown_to_html(markdown) ==
~s|<p><a href="http://example.com/?a=x%22onerror=alert(1)">click</a></p>|
end
assert html =~ ~s|href="http://example.com/?a=x"|
refute html =~ "onerror"
test "keeps URLs with encoded quotes complete" do
markdown = "[search](https://example.org/?q=&quot;cat&quot;&page=2)"
assert Formatter.markdown_to_html(markdown) ==
~s(<p><a href="https://example.org/?q=%22cat%22&amp;page=2">search</a></p>)
end
test "strips email autolinks without changing explicit mailto links" do

View file

@ -232,7 +232,7 @@ defmodule Pleroma.Web.CommonAPI.UtilsTest do
code = ~s|[click](http://example.com/?a=x" onerror="alert(1))|
{result, [], []} = Utils.format_input(code, "text/markdown")
assert result =~ ~s(<a href="http://example.com/?a=x">)
assert result =~ ~s|<a href="http://example.com/?a=x%22 onerror=%22alert(1)">|
refute result =~ ~s|onerror="alert(1)|
refute result =~ ~s(<a href="http://example.com/?a=x" onerror=)
end