java-topology/defects/phoenix/patch/phoenix-0002-router-scope-pipes-mapset.patch

47 lines
1.8 KiB
Diff

# UNDF: UNDF-2026-000000212
From 2db25de Phoenix HEAD (2026-03-27)
Subject: [PATCH phoenix-0002] Fix CWE-407: use MapSet for router scope pipes accumulation
The Scope struct's `pipes` field is a plain list. `pipe_through/2` does
`Enum.find(new_pipes, &(&1 in pipes))` — O(n*m) — for duplicate detection,
then `pipes ++ new_pipes` — O(n) — for accumulation.
Change the `pipes` field default to `MapSet.new()`. Use `MapSet.member?/2`
for the duplicate check and `Enum.reduce/MapSet.put` for accumulation.
This is compile-time only so the practical impact is small, but the pattern
is wrong and MapSet is the correct data structure.
CWE-407: Algorithmic Complexity (Inefficient Algorithmic Complexity)
---
lib/phoenix/router/scope.ex | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/lib/phoenix/router/scope.ex b/lib/phoenix/router/scope.ex
index xxxxxxx..yyyyyyy 100644
--- a/lib/phoenix/router/scope.ex
+++ b/lib/phoenix/router/scope.ex
@@ -9,7 +9,7 @@ defmodule Phoenix.Router.Scope do
defstruct path: [],
alias: [],
as: [],
- pipes: [],
+ pipes: MapSet.new(),
hosts: [],
private: %{},
assigns: %{},
@@ -121,10 +121,12 @@ defmodule Phoenix.Router.Scope do
def pipe_through(module, new_pipes) do
new_pipes = List.wrap(new_pipes)
%{pipes: pipes} = top = get_top(module)
- if pipe = Enum.find(new_pipes, &(&1 in pipes)) do
+ if pipe = Enum.find(new_pipes, &MapSet.member?(pipes, &1)) do
raise ArgumentError,
"duplicate pipe_through for #{inspect(pipe)}. " <>
"A plug may only be used once inside a scoped pipe_through"
end
- put_top(module, %{top | pipes: pipes ++ new_pipes})
+ put_top(module, %{top | pipes: Enum.reduce(new_pipes, pipes, &MapSet.put(&2, &1))})
end