瀏覽代碼

Merge pull request #14180 from zmstone/241107-fix-variform-expression-root-level-undefined-ref

241107 fix variform expression when value is 'undefined'
zmstone 1 年之前
父節點
當前提交
2ce29be173

+ 1 - 0
apps/emqx_utils/src/emqx_variform.erl

@@ -96,6 +96,7 @@ eval_render(Expr, Bindings, Opts) ->
     end.
 
 %% Force the expression to return binary string (in most cases).
+return_str(X) when ?IS_EMPTY(X) -> <<"">>;
 return_str(Str) when is_binary(Str) -> Str;
 return_str(Num) when is_integer(Num) -> integer_to_binary(Num);
 return_str(Num) when is_float(Num) -> float_to_binary(Num, [{decimals, 10}, compact]);

+ 2 - 10
apps/emqx_utils/src/emqx_variform_bif.erl

@@ -421,11 +421,9 @@ any_to_str(Data) ->
 %% Random functions
 %%------------------------------------------------------------------------------
 
-%% @doc Make a random string with urlsafe-base64 charset.
+%% @doc Make a random string with urlsafe-base62 charset.
 rand_str(Length) when is_integer(Length) andalso Length > 0 ->
-    RawBytes = erlang:ceil((Length * 3) / 4),
-    RandomData = rand:bytes(RawBytes),
-    urlsafe(binary:part(base64_encode(RandomData), 0, Length));
+    emqx_utils:rand_id(Length);
 rand_str(_) ->
     throw(#{reason => badarg, function => ?FUNCTION_NAME}).
 
@@ -435,12 +433,6 @@ rand_int(N) when is_integer(N) andalso N >= 1 ->
 rand_int(N) ->
     throw(#{reason => badarg, function => ?FUNCTION_NAME, expected => "positive integer", got => N}).
 
-%% TODO: call base64:encode(Bin, #{mode => urlsafe, padding => false})
-%% when oldest OTP to support is 26 or newer.
-urlsafe(Str0) ->
-    Str = replace(Str0, <<"+">>, <<"-">>),
-    replace(Str, <<"/">>, <<"_">>).
-
 %%------------------------------------------------------------------------------
 %% Data encoding
 %%------------------------------------------------------------------------------

+ 12 - 0
apps/emqx_utils/test/emqx_variform_tests.erl

@@ -26,6 +26,18 @@
 render_test_() ->
     [
         {"direct var reference", fun() -> ?assertEqual({ok, <<"1">>}, render("a", #{a => 1})) end},
+        {"direct var reference missing", fun() ->
+            ?assertMatch({error, #{reason := var_unbound}}, render("a", #{}))
+        end},
+        {"direct var reference undefined", fun() ->
+            ?assertEqual({ok, <<"">>}, render("a", #{a => undefined}))
+        end},
+        {"direct var reference null", fun() ->
+            ?assertEqual({ok, <<"">>}, render("a", #{a => null}))
+        end},
+        {"direct var reference emptry str", fun() ->
+            ?assertEqual({ok, <<"">>}, render("a", #{a => <<>>}))
+        end},
         {"concat strings", fun() ->
             ?assertEqual({ok, <<"a,b">>}, render("concat(['a',',','b'])", #{}))
         end},

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

@@ -0,0 +1 @@
+Fix variform expression to return empty string instead of 'undefined' when a variable is bound to value 'undefined' or 'null'