# UNDF: UNDF-2026-000000239 --- a/deps/rabbit/src/rabbit_classic_queue.erl +++ b/deps/rabbit/src/rabbit_classic_queue.erl @@ -9,7 +9,7 @@ %% TODO possible to use sets / maps instead of lists? %% Check performance with QoS 1 and 1 million target queues. --record(msg_status, {pending :: [pid()], - confirmed = [] :: [pid()]}). +-record(msg_status, {pending :: #{pid() => true}, %% CWE-407 fix: O(1) membership via map + confirmed = [] :: [pid()]}). -define(STATE, ?MODULE). -record(?STATE, { @@ -406,8 +406,8 @@ handle_event(QName, {down, Pid, Info}, #?STATE{monitored = Monitored, false -> MsgSeqNos = maps:keys( maps:filter(fun (_, #msg_status{pending = Pids}) -> - lists:member(Pid, Pids) + maps:is_key(Pid, Pids) %% CWE-407 fix: O(1) map lookup end, U0)), {Unconfirmed, Settled, Rejected} = settle_seq_nos(MsgSeqNos, Pid, U0, down), @@ -428,8 +428,8 @@ handle_event(QName, {down, Pid, Info}, #?STATE{monitored = Monitored, true -> MsgIds = maps:fold( fun (SeqNo, Status, Acc) -> - case lists:member(Pid, Status#msg_status.pending) of + case maps:is_key(Pid, Status#msg_status.pending) of %% CWE-407 fix: O(1) map lookup true -> [SeqNo | Acc]; false -> @@ -591,7 +591,7 @@ qpids(Qs, Confirm, MsgNo) -> #?STATE{unconfirmed = U0} -> - Rec = [QPid], + Rec = #{QPid => true}, %% CWE-407 fix: initialise pending as map/set U = case Confirm of false -> U0; @@ -683,10 +683,10 @@ settle_seq_nos(MsgSeqNos, Pid, U0, Reason) -> #{SeqNo := Status0} -> case update_msg_status(Reason, Pid, Status0) of - #msg_status{pending = [], - confirmed = []} -> + #msg_status{pending = P, confirmed = []} when map_size(P) =:= 0 -> %% CWE-407 fix: empty-map guard %% no pending left and nothing confirmed %% then we reject it {maps:remove(SeqNo, U), C0, [SeqNo | R0]}; - #msg_status{pending = [], - confirmed = _} -> + #msg_status{pending = P2, confirmed = _} when map_size(P2) =:= 0 -> %% CWE-407 fix: empty-map guard %% this can be confirmed as there are no pending %% and confirmed isn't empty {maps:remove(SeqNo, U), [SeqNo | C0], R0}; @@ -704,9 +704,9 @@ settle_seq_nos(MsgSeqNos, Pid, U0, Reason) -> update_msg_status(confirm, Pid, #msg_status{pending = P, confirmed = C} = S) -> - Rem = lists:delete(Pid, P), + Rem = maps:remove(Pid, P), %% CWE-407 fix: O(log N) map remove vs O(P) list scan S#msg_status{pending = Rem, confirmed = [Pid | C]}; update_msg_status(down, Pid, #msg_status{pending = P} = S) -> - S#msg_status{pending = lists:delete(Pid, P)}. + S#msg_status{pending = maps:remove(Pid, P)}. %% CWE-407 fix: O(log N) map remove vs O(P) list scan