java-topology/defects/erlang/patch/erlang-0001-one-path-sets.patch
russell@unturf.com 0a580b313d undefect. CWE-407 — 63 sites patched across 27 ecosystems
Authors: russell@unturf.com · brackishbert@gmail.com · foxhop.net · TimeHexOn.com

Patches, unit tests, benchmarks, whitepaper, and outreach briefs.
Public domain — no copyright claimed. Use freely.
2026-03-26 17:11:57 -04:00

38 lines
1.5 KiB
Diff

diff --git a/lib/stdlib/src/digraph.erl b/lib/stdlib/src/digraph.erl
index a38d242..f6bce33 100644
--- a/lib/stdlib/src/digraph.erl
+++ b/lib/stdlib/src/digraph.erl
@@ -743,7 +743,7 @@ If a [loop](`m:digraph#loop`) through `V` exists, the loop is returned as a list
Vertices :: [vertex(),...].
get_cycle(G, V) ->
- case one_path(out_neighbours(G, V), V, [], [V], [V], 2, G, 1) of
+ case one_path(out_neighbours(G, V), V, [], sets:from_list([V]), [V], 2, G, 1) of
false ->
case lists:member(V, out_neighbours(G, V)) of
true -> [V];
@@ -774,7 +774,7 @@ returned.
Vertices :: [vertex(),...].
get_path(G, V1, V2) ->
- one_path(out_neighbours(G, V1), V2, [], [V1], [V1], 1, G, 1).
+ one_path(out_neighbours(G, V1), V2, [], sets:from_list([V1]), [V1], 1, G, 1).
%%
%% prune_short_path (evaluate conditions on path)
@@ -792,10 +792,12 @@ one_path([W|Ws], W, Cont, Xs, Ps, Prune, G, Counter) ->
ok -> lists:reverse([W|Ps])
end;
one_path([V|Vs], W, Cont, Xs, Ps, Prune, G, Counter) ->
- case lists:member(V, Xs) of
+ %% CWE-407 fix: sets:is_element/2 is O(1) vs lists:member/2 O(n).
+ %% Xs is now a sets:set() instead of a list.
+ case sets:is_element(V, Xs) of
true -> one_path(Vs, W, Cont, Xs, Ps, Prune, G, Counter);
- false -> one_path(out_neighbours(G, V), W,
- [{Vs,Ps} | Cont], [V|Xs], [V|Ps],
+ false -> one_path(out_neighbours(G, V), W,
+ [{Vs,Ps} | Cont], sets:add_element(V, Xs), [V|Ps],
Prune, G, Counter+1)
end;
one_path([], W, [{Vs,Ps}|Cont], Xs, _, Prune, G, Counter) ->