ap/transmogrifier: fix attachment MIME extraction
All checks were successful
ci/woodpecker/pr/test/2 Pipeline was successful
ci/woodpecker/pr/test/1 Pipeline was successful
ci/woodpecker/push/docs Pipeline was successful
ci/woodpecker/push/publish/4 Pipeline was successful
ci/woodpecker/push/publish/1 Pipeline was successful
ci/woodpecker/push/publish/2 Pipeline was successful

If an attachment with a full Link object as an "url" (i.e. a map)
but no "mediaType" attribute in the Link made it to this point
processing crashed since MIME.extensions/1 requires binary input.

Additionally the is_bitstring/1 checks in the other branches were too
lax; bitstrings may contain any number of bits not just full bytes.
This commit is contained in:
Oneric 2026-03-30 00:00:00 +00:00
commit 0b061090ac
2 changed files with 110 additions and 3 deletions

View file

@ -290,6 +290,10 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
|> Map.drop(["conversation"])
end
defp is_valid_mime(mimestr) do
is_binary(mimestr) && MIME.extensions(mimestr) != []
end
def fix_attachments(%{"attachment" => attachment} = object) when is_list(attachment) do
attachments =
Enum.map(attachment, fn data ->
@ -302,13 +306,13 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
media_type =
cond do
is_map(url) && MIME.extensions(url["mediaType"]) != [] ->
is_map(url) && is_valid_mime(url["mediaType"]) ->
url["mediaType"]
is_bitstring(data["mediaType"]) && MIME.extensions(data["mediaType"]) != [] ->
is_valid_mime(data["mediaType"]) ->
data["mediaType"]
is_bitstring(data["mimeType"]) && MIME.extensions(data["mimeType"]) != [] ->
is_valid_mime(data["mimeType"]) ->
data["mimeType"]
true ->

View file

@ -831,6 +831,109 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
assert Transmogrifier.fix_attachments(object) == expected
end
test "can deal with non-array attachment" do
object = %{
"attachment" => %{
"type" => "Document",
"name" => "Hello world",
"url" => "https://media.example.tld/1.jpg",
"mediaType" => "image/jpeg"
}
}
expected = %{
"attachment" => [
%{
"type" => "Document",
"name" => "Hello world",
"url" => [
%{
"type" => "Link",
"mediaType" => "image/jpeg",
"href" => "https://media.example.tld/1.jpg"
}
],
"mediaType" => "image/jpeg"
}
]
}
assert Transmogrifier.fix_attachments(object) == expected
end
test "can deal with missing MIME type" do
object_flat = %{
"attachment" => [
%{
"type" => "Document",
"name" => "Hello world",
"url" => "https://media.example.tld/1.jpg"
}
]
}
object_url_map = %{
"attachment" => [
%{
"type" => "Document",
"name" => "Hello world",
"url" => %{
"type" => "Link",
"href" => "https://media.example.tld/1.jpg"
}
}
]
}
expected = %{
"attachment" => [
%{
"type" => "Document",
"name" => "Hello world",
"url" => [
%{
"type" => "Link",
"href" => "https://media.example.tld/1.jpg"
}
]
}
]
}
assert Transmogrifier.fix_attachments(object_flat) == expected
assert Transmogrifier.fix_attachments(object_url_map) == expected
end
test "rejects invalid MIME type" do
object = %{
"attachment" => [
%{
"type" => "Document",
"name" => "Hello world",
"url" => "https://media.example.tld/1.jpg",
"mediaType" => "apzlicatonne/quark"
}
]
}
expected = %{
"attachment" => [
%{
"type" => "Document",
"name" => "Hello world",
"url" => [
%{
"type" => "Link",
"href" => "https://media.example.tld/1.jpg"
}
]
}
]
}
assert Transmogrifier.fix_attachments(object) == expected
end
end
describe "prepare_object/1" do