Просмотр исходного кода

Merge pull request #12653 from kjellwinblad/kjell/rule_engine/fix/subbits/support_non_byte_sizes/EMQX-11943

fix(rule_engine): support non-byte sized input to bin2hexstr
Kjell Winblad 1 год назад
Родитель
Сommit
060e02c4c4

+ 14 - 1
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 = <<Padding/bitstring, Bin/bitstring>>,
+    <<_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 = <<Padding/bitstring, Bin/bitstring>>,
+    emqx_utils:bin_to_hexstr(BinToConvert, upper).
 
 hexstr2bin(Str) when is_binary(Str) ->
     emqx_utils:hexstr_to_bin(Str).

+ 18 - 0
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
 %%------------------------------------------------------------------------------

+ 1 - 0
changes/ce/fix-12653.en.md

@@ -0,0 +1 @@
+The rule engine function `bin2hexstr` now supports bitstring inputs with a bit size that is not divisible by 8. Such bitstrings can be returned by the rule engine function `subbits`.