From a17c2c166de11b8e19342df145bcbc6a18d6c868 Mon Sep 17 00:00:00 2001 From: Pawel Chmielowski Date: Wed, 16 Jul 2025 12:19:51 +0200 Subject: [PATCH] Fix issue with filtering duplicates in auth_mnesia:get_users() Previous version was only correct when data to process was sorted, which was not always the case. This add common implementation of lists:uniq in misc that works also on Users = mnesia:dirty_select(passwd, [{#passwd{us = '$1', _ = '_'}, [{'==', {element, 2, '$1'}, Server}], ['$1']}]), - {_, Res} = lists:foldl( - fun({U, S, _}, {{U2, S2}, _} = Acc) when U == U2 andalso S == S2 -> - Acc; - ({U, S, _}, {_, Res}) -> - {{U, S}, [{U, S} | Res]} - end, {{none, none}, []}, Users), - Res; + misc:lists_uniq([{U, S} || {U, S, _} <- Users]); get_users(Server, [{from, Start}, {to, End}]) when is_integer(Start) and is_integer(End) -> get_users(Server, [{limit, End - Start + 1}, {offset, Start}]); diff --git a/src/ejabberd_config.erl b/src/ejabberd_config.erl index c4c01eb79..4ad1afd3f 100644 --- a/src/ejabberd_config.erl +++ b/src/ejabberd_config.erl @@ -631,22 +631,7 @@ callback_modules(external) -> end end, beams(external)); callback_modules(all) -> - lists_uniq(callback_modules(local) ++ callback_modules(external)). - --ifdef(OTP_BELOW_25). -lists_uniq(List) -> - {Res, _} = lists:foldr( - fun(El, {Result, Existing} = Acc) -> - case maps:is_key(El, Existing) of - true -> Acc; - _ -> {[El | Result], Existing#{El => true}} - end - end, {[], #{}}, List), - Res. --else. -lists_uniq(List) -> - lists:uniq(List). --endif. + misc:lists_uniq(callback_modules(local) ++ callback_modules(external)). -spec validators(module(), [atom()], [any()]) -> econf:validators(). validators(Mod, Disallowed, DK) -> diff --git a/src/misc.erl b/src/misc.erl index 0ddc85996..55c1cec29 100644 --- a/src/misc.erl +++ b/src/misc.erl @@ -46,7 +46,8 @@ json_encode/1, json_decode/1, set_proc_label/1, match_ip_mask/3, format_hosts_list/1, format_cycle/1, delete_dir/1, - semver_to_xxyy/1, logical_processors/0, get_mucsub_event_type/1]). + semver_to_xxyy/1, logical_processors/0, get_mucsub_event_type/1, + lists_uniq/1]). %% Deprecated functions -export([decode_base64/1, encode_base64/1]). @@ -819,3 +820,21 @@ set_proc_label(_Label) -> set_proc_label(Label) -> proc_lib:set_label(Label). -endif. + +-ifdef(OTP_BELOW_25). +-spec lists_uniq([term()]) -> [term()]. +lists_uniq(List) -> + lists_uniq_int(List, #{}). + +lists_uniq_int([El | Rest], Existing) -> + case maps:is_key(El, Existing) of + true -> lists_uniq_int(Rest, Existing); + _ -> [El | lists_uniq_int(Rest, Existing#{El => true})] + end; +lists_uniq_int([], _) -> + []. +-else. +-spec lists_uniq([term()]) -> [term()]. +lists_uniq(List) -> + lists:uniq(List). +-endif.