diff --git a/lib/pleroma/web/xml.ex b/lib/pleroma/web/xml.ex
index ba8886548..e68341e20 100644
--- a/lib/pleroma/web/xml.ex
+++ b/lib/pleroma/web/xml.ex
@@ -26,13 +26,7 @@ def string_from_xpath(xpath, doc) do
def parse_document(text) do
try do
- {doc, _rest} =
- text
- |> :binary.bin_to_list()
- |> :xmerl_scan.string(
- quiet: true,
- allow_entities: false
- )
+ doc = SweetXml.parse(text, dtd: :none)
{:ok, doc}
rescue
diff --git a/mix.exs b/mix.exs
index 5ffbf0fe7..5aa1381d5 100644
--- a/mix.exs
+++ b/mix.exs
@@ -204,6 +204,7 @@ defp deps do
{:mox, "~> 1.0", only: :test},
{:websockex, "~> 0.4.3", only: :test},
{:dialyxir, "~> 1.3", only: [:dev], runtime: false},
+ {:elixir_xml_to_map, "~> 3.0", only: :test},
{:mint, "~> 1.5.1", override: true},
{:nimble_pool, "~> 1.0", override: true}
] ++ oauth_deps()
diff --git a/mix.lock b/mix.lock
index aab94708c..471e61750 100644
--- a/mix.lock
+++ b/mix.lock
@@ -33,7 +33,9 @@
"ecto_sql": {:hex, :ecto_sql, "3.10.1", "6ea6b3036a0b0ca94c2a02613fd9f742614b5cfe494c41af2e6571bb034dd94c", [:mix], [{:db_connection, "~> 2.4.1 or ~> 2.5", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.10.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.6.0", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.16.0 or ~> 0.17.0 or ~> 1.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:tds, "~> 2.1.1 or ~> 2.2", [hex: :tds, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "f6a25bdbbd695f12c8171eaff0851fa4c8e72eec1e98c7364402dda9ce11c56b"},
"elasticsearch": {:git, "https://akkoma.dev/AkkomaGang/elasticsearch-elixir.git", "6cd946f75f6ab9042521a009d1d32d29a90113ca", [ref: "main"]},
"elixir_make": {:hex, :elixir_make, "0.7.7", "7128c60c2476019ed978210c245badf08b03dbec4f24d05790ef791da11aa17c", [:mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}], "hexpm", "5bc19fff950fad52bbe5f211b12db9ec82c6b34a9647da0c2224b8b8464c7e6c"},
+ "elixir_xml_to_map": {:hex, :elixir_xml_to_map, "3.0.0", "67dcff30ecf72aed37ab08525133e4420717a749436e22bfece431e7dddeea7e", [:mix], [{:erlsom, "~> 1.4", [hex: :erlsom, repo: "hexpm", optional: false]}], "hexpm", "11222dd7f029f8db7a6662b41c992dbdb0e1c6e4fdea6a42056f9d27c847efbb"},
"erlex": {:hex, :erlex, "0.2.6", "c7987d15e899c7a2f34f5420d2a2ea0d659682c06ac607572df55a43753aa12e", [:mix], [], "hexpm", "2ed2e25711feb44d52b17d2780eabf998452f6efda104877a3881c2f8c0c0c75"},
+ "erlsom": {:hex, :erlsom, "1.5.1", "c8fe2babd33ff0846403f6522328b8ab676f896b793634cfe7ef181c05316c03", [:rebar3], [], "hexpm", "7965485494c5844dd127656ac40f141aadfa174839ec1be1074e7edf5b4239eb"},
"eternal": {:hex, :eternal, "1.2.2", "d1641c86368de99375b98d183042dd6c2b234262b8d08dfd72b9eeaafc2a1abd", [:mix], [], "hexpm", "2c9fe32b9c3726703ba5e1d43a1d255a4f3f2d8f8f9bc19f094c7cb1a7a9e782"},
"ex_aws": {:hex, :ex_aws, "2.4.4", "d7886eaca7e10f7bd3d9e9d2d5414cb336737b3ab2fddd4fa30358b725293fe0", [:mix], [{:configparser_ex, "~> 4.0", [hex: :configparser_ex, repo: "hexpm", optional: true]}, {:hackney, "~> 1.16", [hex: :hackney, repo: "hexpm", optional: true]}, {:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: true]}, {:jsx, "~> 2.8 or ~> 3.0", [hex: :jsx, repo: "hexpm", optional: true]}, {:mime, "~> 1.2 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:sweet_xml, "~> 0.7", [hex: :sweet_xml, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "a7d63e485ca2b16fb804f3f20097827aa69885eea6e69fa75c98f353c9c91dc7"},
"ex_aws_s3": {:hex, :ex_aws_s3, "2.4.0", "ce8decb6b523381812798396bc0e3aaa62282e1b40520125d1f4eff4abdff0f4", [:mix], [{:ex_aws, "~> 2.0", [hex: :ex_aws, repo: "hexpm", optional: false]}, {:sweet_xml, ">= 0.0.0", [hex: :sweet_xml, repo: "hexpm", optional: true]}], "hexpm", "85dda6e27754d94582869d39cba3241d9ea60b6aa4167f9c88e309dc687e56bb"},
diff --git a/test/fixtures/xml_normal.xml b/test/fixtures/xml_normal.xml
new file mode 100644
index 000000000..8dfa0af54
--- /dev/null
+++ b/test/fixtures/xml_normal.xml
@@ -0,0 +1,44 @@
+
+
+
+
+ Match One
+
+
+ 1
+ Team One
+
+
+ 2
+ Team Two
+
+
+
+
+ Match Two
+
+
+ 2
+ Team Two
+
+
+ 3
+ Team Three
+
+
+
+
+ Match Three
+
+
+ 1
+ Team One
+
+
+ 3
+ Team Three
+
+
+
+
+
diff --git a/test/pleroma/web/web_finger/web_finger_controller_test.exs b/test/pleroma/web/web_finger/web_finger_controller_test.exs
index 6b5b7c46c..929ebbed0 100644
--- a/test/pleroma/web/web_finger/web_finger_controller_test.exs
+++ b/test/pleroma/web/web_finger/web_finger_controller_test.exs
@@ -8,6 +8,7 @@ defmodule Pleroma.Web.WebFinger.WebFingerControllerTest do
import ExUnit.CaptureLog
import Pleroma.Factory
import Tesla.Mock
+ import Pleroma.Test.Matchers.XML
setup do
mock(fn env -> apply(HttpRequestMock, :request, [env]) end)
@@ -23,8 +24,8 @@ test "GET host-meta" do
assert response.status == 200
- assert response.resp_body ==
- ~s()
+ assert_xml_equals(response.resp_body,
+ ~s())
end
test "Webfinger JRD" do
diff --git a/test/pleroma/web/xml_test.exs b/test/pleroma/web/xml_test.exs
index 49306430b..0dc8d299e 100644
--- a/test/pleroma/web/xml_test.exs
+++ b/test/pleroma/web/xml_test.exs
@@ -3,6 +3,11 @@ defmodule Pleroma.Web.XMLTest do
alias Pleroma.Web.XML
+ test "parses normal XML" do
+ data = File.read!("test/fixtures/xml_normal.xml")
+ assert {:ok, _} = XML.parse_document(data)
+ end
+
test "refuses to parse any entities from XML" do
data = File.read!("test/fixtures/xml_billion_laughs.xml")
assert(:error == XML.parse_document(data))
diff --git a/test/support/matchers/xml.ex b/test/support/matchers/xml.ex
new file mode 100644
index 000000000..9f260ce82
--- /dev/null
+++ b/test/support/matchers/xml.ex
@@ -0,0 +1,18 @@
+defmodule Pleroma.Test.Matchers.XML do
+ import ExUnit.Assertions
+
+ def assert_xml_equals(xml_a, xml_b) do
+ map_a = XmlToMap.naive_map(xml_a)
+ map_b = XmlToMap.naive_map(xml_b)
+
+ if map_a != map_b do
+ flunk(~s|Expected XML
+ #{xml_a}
+
+ to equal
+
+ #{xml_b}
+ |)
+ end
+ end
+end