wave16: dart-0001/2/3 + octave-0002 + php-0003/4 + cassandra-0005 + erlang-0003 + chef-0001 — 542/240

This commit is contained in:
russell@unturf.com 2026-03-27 19:36:35 -04:00
parent 31850d5ef6
commit d816d3c74c
18 changed files with 1902 additions and 6 deletions

View file

@ -0,0 +1,29 @@
--- a/lib/kernel/src/code_server.erl
+++ b/lib/kernel/src/code_server.erl
@@ -598,14 +598,19 @@ merge_path(Path,IPath,Acc) ->
merge_path1(Path,IPath,Acc).
-merge_path1([P|Path],IPath,Acc) ->
- case lists:member(P,Acc) of
+%% CWE-407 fix: merge_path1 used a plain list (Acc) as a seen-set.
+%% lists:member/2 is O(|Acc|); called once per element of Path, total cost
+%% is O(|Path|²) when all paths are unique. On a system with N library
+%% directories (common in large OTP/Elixir/Erlang deployments), this
+%% runs at startup and every code:add_paths/1 call.
+%% Fix: carry a sets:set() alongside the accumulator list for O(1) membership.
+merge_path1([P|Path],IPath,Acc) ->
+ merge_path1([P|Path],IPath,Acc,sets:new()).
+
+merge_path1([P|Path],IPath,Acc,Seen) ->
+ case sets:is_element(P,Seen) of
true ->
- merge_path1(Path,IPath,Acc); % Already added
+ merge_path1(Path,IPath,Acc,Seen); % Already added
false ->
IPath1 = exclude(P,IPath),
- merge_path1(Path,IPath1,[P|Acc])
+ merge_path1(Path,IPath1,[P|Acc],sets:add_element(P,Seen))
end;
-merge_path1(_,IPath,Acc) ->
+merge_path1(_,IPath,Acc,_Seen) ->
lists:reverse(Acc) ++ IPath.