Skip to content

Commit 8fb466e

Browse files
authored
Raise on list value in query string parameter encoding (#6632)
When a plain list is interpolated as a query string value (e.g., ~p"/path?key=#{[value]}"), raise an ArgumentError with a helpful message pointing to the correct syntax (~p"/path?#{[key: [value]]}"). Previously, the list was silently treated as a dict by Plug.Conn.Query.encode, producing incorrect output like "key=[]=value". Closes #6582
1 parent eca672e commit 8fb466e

File tree

2 files changed

+24
-2
lines changed

2 files changed

+24
-2
lines changed

lib/phoenix/verified_routes.ex

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -891,14 +891,26 @@ defmodule Phoenix.VerifiedRoutes do
891891
@doc false
892892
def __encode_query__(dict, sort? \\ false)
893893

894-
def __encode_query__(dict, sort?)
895-
when is_list(dict) or (is_map(dict) and not is_struct(dict)) do
894+
def __encode_query__(dict, sort?) when is_map(dict) and not is_struct(dict) do
896895
case Plug.Conn.Query.encode(dict, &to_param/1) do
897896
"" -> ""
898897
query_str -> maybe_sort_query(query_str, sort?)
899898
end
900899
end
901900

901+
def __encode_query__(dict, sort?) when is_list(dict) do
902+
if dict == [] or match?([{_, _} | _], dict) do
903+
case Plug.Conn.Query.encode(dict, &to_param/1) do
904+
"" -> ""
905+
query_str -> maybe_sort_query(query_str, sort?)
906+
end
907+
else
908+
raise ArgumentError,
909+
"expected a keyword list or map for query string encoding, got: #{inspect(dict)}. " <>
910+
"Use the full query string syntax instead, such as ~p\"/path?#\{[key: #{inspect(dict)}]}\""
911+
end
912+
end
913+
902914
def __encode_query__(val, _sort?), do: val |> to_param() |> URI.encode_www_form()
903915

904916
defp maybe_sort_query(query_str, false), do: query_str

test/phoenix/verified_routes_test.exs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,16 @@ defmodule Phoenix.VerifiedRoutesTest do
418418
:code.delete(__MODULE__.InvalidQuery)
419419
end
420420

421+
test "list value as query string parameter raises" do
422+
assert_raise ArgumentError, ~r/expected a keyword list or map/, fn ->
423+
~p"/posts/top?#{["abc-123"]}"
424+
end
425+
426+
assert_raise ArgumentError, ~r/expected a keyword list or map/, fn ->
427+
~p"/posts/top?#{[1, 2, 3]}"
428+
end
429+
end
430+
421431
test "~p with complex ids" do
422432
assert ~p|/posts/#{"==d--+"}| == "/posts/%3D%3Dd--%2B"
423433
assert ~p|/posts/top?#{[id: "==d--+"]}| == "/posts/top?id=%3D%3Dd--%2B"

0 commit comments

Comments
 (0)