commit: 0f3b1808fd3dc835e0fe993ceb16ec4d6ea12c03
parent cc14a7e33bd5af2ed7b0081e47deb526ccef0616
Author: Phantasm <phantasm@centrum.cz>
Date: Thu, 14 Aug 2025 22:03:23 +0200
Check what chars to encode in the path segment of URIs, add list to Constants
https://datatracker.ietf.org/doc/html/rfc3986
Diffstat:
2 files changed, 18 insertions(+), 1 deletion(-)
diff --git a/lib/pleroma/constants.ex b/lib/pleroma/constants.ex
@@ -132,6 +132,13 @@ defmodule Pleroma.Constants do
do: ~r/^[^[:cntrl:] ()<>@,;:\\"\/\[\]?=]+\/[^[:cntrl:] ()<>@,;:\\"\/\[\]?=]+(; .*)?$/
)
+ # List of allowed chars in the path segment of a URI
+ # unreserved, sub-delims, ":", "@" and "/" allowed as the separator in path
+ # https://datatracker.ietf.org/doc/html/rfc3986
+ const(uri_path_allowed_reserved_chars,
+ do: ~c"!$&'()*+,;=/:@"
+ )
+
const(upload_object_types, do: ["Document", "Image"])
const(activity_json_canonical_mime_type,
diff --git a/lib/pleroma/http.ex b/lib/pleroma/http.ex
@@ -14,6 +14,7 @@ defmodule Pleroma.HTTP do
alias Tesla.Env
require Logger
+ require Pleroma.Constants
@type t :: __MODULE__
@type method() :: :get | :post | :put | :delete | :head
@@ -145,10 +146,19 @@ defmodule Pleroma.HTTP do
defp encode_path(nil), do: nil
+ # URI.encode/2 deliberately does not encode all chars that are forbidden
+ # in the path component of a URI. It only encodes chars that are forbidden
+ # in the whole URI. A predicate in the 2nd argument is used to fix that here.
+ # URI.encode/2 uses the predicate function to determine whether each byte
+ # (in an integer representation) should be encoded or not.
defp encode_path(path) when is_binary(path) do
path
|> URI.decode()
- |> URI.encode()
+ |> URI.encode(fn byte ->
+ URI.char_unreserved?(byte) || Enum.any?(
+ Pleroma.Constants.uri_path_allowed_reserved_chars, fn char ->
+ char == byte end)
+ end)
end
defp encode_query(nil), do: nil