From 9cf03bb18a1977f157169d4b386551e6c0bdec0b Mon Sep 17 00:00:00 2001 From: JianBo He Date: Wed, 5 Jan 2022 10:45:51 +0800 Subject: [PATCH 1/2] fix(mgmt): fix substring matching alg --- .../src/emqx_mgmt_api_clients.erl | 40 +++++++++++-------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/apps/emqx_management/src/emqx_mgmt_api_clients.erl b/apps/emqx_management/src/emqx_mgmt_api_clients.erl index 1ddd87a3d..eaa6bf601 100644 --- a/apps/emqx_management/src/emqx_mgmt_api_clients.erl +++ b/apps/emqx_management/src/emqx_mgmt_api_clients.erl @@ -333,31 +333,24 @@ query({Qs, Fuzzy}, Start, Limit) -> match_fun(Ms, Fuzzy) -> MsC = ets:match_spec_compile(Ms), - REFuzzy = lists:map(fun({K, like, S}) -> - {ok, RE} = re:compile(escape(S)), - {K, like, RE} - end, Fuzzy), fun(Rows) -> case ets:match_spec_run(Rows, MsC) of [] -> []; Ls -> lists:filter(fun(E) -> - run_fuzzy_match(E, REFuzzy) + run_fuzzy_match(E, Fuzzy) end, Ls) end end. -escape(B) when is_binary(B) -> - re:replace(B, <<"\\\\">>, <<"\\\\\\\\">>, [{return, binary}, global]). - run_fuzzy_match(_, []) -> true; -run_fuzzy_match(E = {_, #{clientinfo := ClientInfo}, _}, [{Key, _, RE}|Fuzzy]) -> - Val = case maps:get(Key, ClientInfo, "") of - undefined -> ""; +run_fuzzy_match(E = {_, #{clientinfo := ClientInfo}, _}, [{Key, like, SubStr}|Fuzzy]) -> + Val = case maps:get(Key, ClientInfo, undefined) of + undefined -> <<>>; V -> V end, - re:run(Val, RE, [{capture, none}]) == match andalso run_fuzzy_match(E, Fuzzy). + binary:match(Val, SubStr) /= nomatch andalso run_fuzzy_match(E, Fuzzy). %%-------------------------------------------------------------------- %% QueryString to Match Spec @@ -453,9 +446,24 @@ params2qs_test() -> [{{'$1', #{}, '_'}, [], ['$_']}] = qs2ms([]). -escape_test() -> - Str = <<"\\n">>, - {ok, Re} = re:compile(escape(Str)), - {match, _} = re:run(<<"\\name">>, Re). +fuzzy_match_test() -> + Info = {emqx_channel_info, + #{clientinfo => + #{ clientid => <<"abcde">> + , username => <<"abc\\name*[]()">> + }}, [] + }, + true = run_fuzzy_match(Info, [{clientid, like, <<"abcde">>}]), + true = run_fuzzy_match(Info, [{clientid, like, <<"bcd">>}]), + false = run_fuzzy_match(Info, [{clientid, like, <<"defh">>}]), + + true = run_fuzzy_match(Info, [{username, like, <<"\\name">>}]), + true = run_fuzzy_match(Info, [{username, like, <<"*">>}]), + true = run_fuzzy_match(Info, [{username, like, <<"[]">>}]), + true = run_fuzzy_match(Info, [{username, like, <<"()">>}]), + false = run_fuzzy_match(Info, [{username, like, <<"))">>}]), + + true = run_fuzzy_match(Info, [{clientid, like, <<"de">>}, + {username, like, <<"[]">>}]). -endif. From d6f56cbcbe3f783eca89ef45dbaa20da839095af Mon Sep 17 00:00:00 2001 From: JianBo He Date: Wed, 5 Jan 2022 11:28:11 +0800 Subject: [PATCH 2/2] fix(mgmt): convert timestamp to milliseconds --- apps/emqx_management/src/emqx_mgmt_api.erl | 8 +++++--- apps/emqx_management/src/emqx_mgmt_api_clients.erl | 8 ++++---- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/apps/emqx_management/src/emqx_mgmt_api.erl b/apps/emqx_management/src/emqx_mgmt_api.erl index e068c5384..c34791b57 100644 --- a/apps/emqx_management/src/emqx_mgmt_api.erl +++ b/apps/emqx_management/src/emqx_mgmt_api.erl @@ -297,10 +297,12 @@ to_integer(I) when is_integer(I) -> to_integer(B) when is_binary(B) -> binary_to_integer(B). +%% @doc The input timestamp time is in seconds, which needs to be +%% converted to internal milliseconds here to_timestamp(I) when is_integer(I) -> - I; + I * 1000; to_timestamp(B) when is_binary(B) -> - binary_to_integer(B). + binary_to_integer(B) * 1000. aton(B) when is_binary(B) -> list_to_tuple([binary_to_integer(T) || T <- re:split(B, "[.]")]). @@ -332,7 +334,7 @@ params2qs_test() -> ExpectedQs = [{str, '=:=', <<"abc">>}, {int, '=:=', 123}, {atom, '=:=', connected}, - {ts, '=:=', 156000}, + {ts, '=:=', 156000000}, {range, '>=', 1, '=<', 5} ], FuzzyQs = [{fuzzy, like, <<"user">>}, diff --git a/apps/emqx_management/src/emqx_mgmt_api_clients.erl b/apps/emqx_management/src/emqx_mgmt_api_clients.erl index eaa6bf601..7d3dbddc8 100644 --- a/apps/emqx_management/src/emqx_mgmt_api_clients.erl +++ b/apps/emqx_management/src/emqx_mgmt_api_clients.erl @@ -435,10 +435,10 @@ params2qs_test() -> proto_ver => 4, connected_at => '$3'}, session => #{created_at => '$2'}}, - ExpectedCondi = [{'>=','$2', 1}, - {'=<','$2', 5}, - {'>=','$3', 1}, - {'=<','$3', 5}], + ExpectedCondi = [{'>=','$2', 1000}, + {'=<','$2', 5000}, + {'>=','$3', 1000}, + {'=<','$3', 5000}], {10, {Qs1, []}} = emqx_mgmt_api:params2qs(Params, QsSchema), [{{'$1', MtchHead, _}, Condi, _}] = qs2ms(Qs1), ?assertEqual(ExpectedMtchHead, MtchHead),