diff options
5 files changed, 77 insertions, 12 deletions
| diff --git a/lib/pleroma/constants.ex b/lib/pleroma/constants.ex index a42c71d23..7b63ab06e 100644 --- a/lib/pleroma/constants.ex +++ b/lib/pleroma/constants.ex @@ -27,4 +27,10 @@ defmodule Pleroma.Constants do      do:        ~w(index.html robots.txt static static-fe finmoji emoji packs sounds images instance sw.js sw-pleroma.js favicon.png schemas doc embed.js embed.css)    ) + +  # basic regex, just there to weed out potential mistakes +  # https://datatracker.ietf.org/doc/html/rfc2045#section-5.1 +  const(mime_regex, +    do: ~r/^[^[:cntrl:] ()<>@,;:\\"\/\[\]?=]+\/[^[:cntrl:] ()<>@,;:\\"\/\[\]?=]+(; .*)?$/ +  )  end diff --git a/lib/pleroma/ecto_type/activity_pub/object_validators/mime.ex b/lib/pleroma/ecto_type/activity_pub/object_validators/mime.ex new file mode 100644 index 000000000..31d51577d --- /dev/null +++ b/lib/pleroma/ecto_type/activity_pub/object_validators/mime.ex @@ -0,0 +1,25 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/> +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.EctoType.ActivityPub.ObjectValidators.MIME do +  use Ecto.Type + +  require Pleroma.Constants + +  def type, do: :string + +  def cast(mime) when is_binary(mime) do +    if mime =~ Pleroma.Constants.mime_regex() do +      {:ok, mime} +    else +      {:ok, "application/octet-stream"} +    end +  end + +  def cast(_), do: :error + +  def dump(data), do: {:ok, data} + +  def load(data), do: {:ok, data} +end diff --git a/lib/pleroma/web/activity_pub/object_validators/attachment_validator.ex b/lib/pleroma/web/activity_pub/object_validators/attachment_validator.ex index d1c61ac82..8b641d88d 100644 --- a/lib/pleroma/web/activity_pub/object_validators/attachment_validator.ex +++ b/lib/pleroma/web/activity_pub/object_validators/attachment_validator.ex @@ -12,14 +12,14 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AttachmentValidator do    @primary_key false    embedded_schema do      field(:type, :string) -    field(:mediaType, :string, default: "application/octet-stream") +    field(:mediaType, ObjectValidators.MIME, default: "application/octet-stream")      field(:name, :string)      field(:blurhash, :string)      embeds_many :url, UrlObjectValidator, primary_key: false do        field(:type, :string)        field(:href, ObjectValidators.Uri) -      field(:mediaType, :string, default: "application/octet-stream") +      field(:mediaType, ObjectValidators.MIME, default: "application/octet-stream")        field(:width, :integer)        field(:height, :integer)      end @@ -59,13 +59,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AttachmentValidator do    end    def fix_media_type(data) do -    data = Map.put_new(data, "mediaType", data["mimeType"]) - -    if is_bitstring(data["mediaType"]) && MIME.extensions(data["mediaType"]) != [] do -      data -    else -      Map.put(data, "mediaType", "application/octet-stream") -    end +    Map.put_new(data, "mediaType", data["mimeType"])    end    defp handle_href(href, mediaType, data) do diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex index a70330f0e..d6622df86 100644 --- a/lib/pleroma/web/activity_pub/transmogrifier.ex +++ b/lib/pleroma/web/activity_pub/transmogrifier.ex @@ -203,13 +203,13 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do          media_type =            cond do -            is_map(url) && MIME.extensions(url["mediaType"]) != [] -> +            is_map(url) && url =~ Pleroma.Constants.mime_regex() ->                url["mediaType"] -            is_bitstring(data["mediaType"]) && MIME.extensions(data["mediaType"]) != [] -> +            is_bitstring(data["mediaType"]) && data["mediaType"] =~ Pleroma.Constants.mime_regex() ->                data["mediaType"] -            is_bitstring(data["mimeType"]) && MIME.extensions(data["mimeType"]) != [] -> +            is_bitstring(data["mimeType"]) && data["mimeType"] =~ Pleroma.Constants.mime_regex() ->                data["mimeType"]              true -> diff --git a/test/pleroma/web/activity_pub/object_validators/attachment_validator_test.exs b/test/pleroma/web/activity_pub/object_validators/attachment_validator_test.exs index b07011b76..9a17e277e 100644 --- a/test/pleroma/web/activity_pub/object_validators/attachment_validator_test.exs +++ b/test/pleroma/web/activity_pub/object_validators/attachment_validator_test.exs @@ -27,6 +27,46 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AttachmentValidatorTest do        assert attachment.mediaType == "application/octet-stream"      end +    test "works with an unknown but valid mime type" do +      attachment = %{ +        "mediaType" => "x-custom/x-type", +        "type" => "Document", +        "url" => "https://example.org" +      } + +      assert {:ok, attachment} = +               AttachmentValidator.cast_and_validate(attachment) +               |> Ecto.Changeset.apply_action(:insert) + +      assert attachment.mediaType == "x-custom/x-type" +    end + +    test "works with invalid mime types" do +      attachment = %{ +        "mediaType" => "x-customx-type", +        "type" => "Document", +        "url" => "https://example.org" +      } + +      assert {:ok, attachment} = +               AttachmentValidator.cast_and_validate(attachment) +               |> Ecto.Changeset.apply_action(:insert) + +      assert attachment.mediaType == "application/octet-stream" + +      attachment = %{ +        "mediaType" => "https://example.org", +        "type" => "Document", +        "url" => "https://example.org" +      } + +      assert {:ok, attachment} = +               AttachmentValidator.cast_and_validate(attachment) +               |> Ecto.Changeset.apply_action(:insert) + +      assert attachment.mediaType == "application/octet-stream" +    end +      test "it turns mastodon attachments into our attachments" do        attachment = %{          "url" => | 
