diff --git a/apps/emqx_rule_engine/src/emqx_rule_funcs.erl b/apps/emqx_rule_engine/src/emqx_rule_funcs.erl index 735025e2b..3cebdd67a 100644 --- a/apps/emqx_rule_engine/src/emqx_rule_funcs.erl +++ b/apps/emqx_rule_engine/src/emqx_rule_funcs.erl @@ -707,7 +707,20 @@ map(Data) -> error(badarg, [Data]). bin2hexstr(Bin) when is_binary(Bin) -> - emqx_utils:bin_to_hexstr(Bin, upper). + emqx_utils:bin_to_hexstr(Bin, upper); +%% If Bin is a bitstring which is not divisible by 8, we pad it and then do the +%% conversion +bin2hexstr(Bin) when is_bitstring(Bin), (8 - (bit_size(Bin) rem 8)) >= 4 -> + PadSize = 8 - (bit_size(Bin) rem 8), + Padding = <<0:PadSize>>, + BinToConvert = <>, + <<_FirstByte:8, HexStr/binary>> = emqx_utils:bin_to_hexstr(BinToConvert, upper), + HexStr; +bin2hexstr(Bin) when is_bitstring(Bin) -> + PadSize = 8 - (bit_size(Bin) rem 8), + Padding = <<0:PadSize>>, + BinToConvert = <>, + emqx_utils:bin_to_hexstr(BinToConvert, upper). hexstr2bin(Str) when is_binary(Str) -> emqx_utils:hexstr_to_bin(Str). diff --git a/apps/emqx_rule_engine/test/emqx_rule_funcs_SUITE.erl b/apps/emqx_rule_engine/test/emqx_rule_funcs_SUITE.erl index 3bdfaa5b4..62c31cc2f 100644 --- a/apps/emqx_rule_engine/test/emqx_rule_funcs_SUITE.erl +++ b/apps/emqx_rule_engine/test/emqx_rule_funcs_SUITE.erl @@ -198,6 +198,19 @@ t_bin2hexstr(_) -> ?assertEqual(<<"0102">>, emqx_rule_funcs:bin2hexstr(<<1, 2>>)), ?assertEqual(<<"1121">>, emqx_rule_funcs:bin2hexstr(<<17, 33>>)). +t_bin2hexstr_not_even_bytes(_) -> + ?assertEqual(<<"0102">>, emqx_rule_funcs:bin2hexstr(<<1:5, 2>>)), + ?assertEqual(<<"1002">>, emqx_rule_funcs:bin2hexstr(<<16:5, 2>>)), + ?assertEqual(<<"1002">>, emqx_rule_funcs:bin2hexstr(<<16:8, 2>>)), + ?assertEqual(<<"102">>, emqx_rule_funcs:bin2hexstr(<<1:4, 2>>)), + ?assertEqual(<<"102">>, emqx_rule_funcs:bin2hexstr(<<1:3, 2>>)), + ?assertEqual(<<"102">>, emqx_rule_funcs:bin2hexstr(<<1:1, 2>>)), + ?assertEqual(<<"002">>, emqx_rule_funcs:bin2hexstr(<<2:1, 2>>)), + ?assertEqual(<<"02">>, emqx_rule_funcs:bin2hexstr(<<2>>)), + ?assertEqual(<<"2">>, emqx_rule_funcs:bin2hexstr(<<2:2>>)), + ?assertEqual(<<"1121">>, emqx_rule_funcs:bin2hexstr(<<17, 33>>)), + ?assertEqual(<<"01121">>, emqx_rule_funcs:bin2hexstr(<<17:9, 33>>)). + t_hex_convert(_) -> ?PROPTEST(hex_convert). @@ -922,6 +935,11 @@ t_subbits_5_args(_) -> apply_func(subbits, [<<456:32/integer>>, 1, 32, <<"integer">>, <<"unsigned">>]) ). +t_subbits_not_even_bytes(_) -> + InputBin = apply_func(hexstr2bin, [<<"9F4E58">>]), + SubbitsRes = apply_func(subbits, [InputBin, 1, 6, <<"bits">>, <<"unsigned">>, <<"big">>]), + ?assertEqual(<<"27">>, apply_func(bin2hexstr, [SubbitsRes])). + %%------------------------------------------------------------------------------ %% Test cases for Hash funcs %%------------------------------------------------------------------------------