Преглед изворни кода

fix: validate range for some bridge options

Fixes https://emqx.atlassian.net/browse/EMQX-9864

Setting a very large interval can cause `erlang:start_timer` to crash.
Also, setting auto_restart_interval or health_check_interval to "0s"
causes the state machine to be in loop as time 0 is handled separately:

| state_timeout() = timeout() | integer()
| (...)
| If Time is relative and 0 no timer is actually started, instead the the
| time-out event is enqueued to ensure that it gets processed before any
| not yet received external event.
from "https://www.erlang.org/doc/man/gen_statem.html#type-state_timeout"

Therefore, both fields are now validated against the range [1ms, 1h],
which doesn't cause above issues.
Paulo Zulato пре 2 година
родитељ
комит
5d289ade56
2 измењених фајлова са 35 додато и 0 уклоњено
  1. 34 0
      apps/emqx_resource/src/schema/emqx_resource_schema.erl
  2. 1 0
      changes/ce/fix-10726.en.md

+ 34 - 0
apps/emqx_resource/src/schema/emqx_resource_schema.erl

@@ -23,6 +23,12 @@
 
 -export([namespace/0, roots/0, fields/1, desc/1]).
 
+%% range interval in ms
+-define(HEALTH_CHECK_INTERVAL_RANGE_MIN, 1).
+-define(HEALTH_CHECK_INTERVAL_RANGE_MAX, 3_600_000).
+-define(AUTO_RESTART_INTERVAL_RANGE_MIN, 1).
+-define(AUTO_RESTART_INTERVAL_RANGE_MAX, 3_600_000).
+
 %% -------------------------------------------------------------------------------------------------
 %% Hocon Schema Definitions
 
@@ -81,8 +87,22 @@ health_check_interval(type) -> emqx_schema:duration_ms();
 health_check_interval(desc) -> ?DESC("health_check_interval");
 health_check_interval(default) -> ?HEALTHCHECK_INTERVAL_RAW;
 health_check_interval(required) -> false;
+health_check_interval(validator) -> fun health_check_interval_range/1;
 health_check_interval(_) -> undefined.
 
+health_check_interval_range(HealthCheckInterval) when
+    is_integer(HealthCheckInterval) andalso
+        HealthCheckInterval >= ?HEALTH_CHECK_INTERVAL_RANGE_MIN andalso
+        HealthCheckInterval =< ?HEALTH_CHECK_INTERVAL_RANGE_MAX
+->
+    ok;
+health_check_interval_range(_HealthCheckInterval) ->
+    {error, #{
+        msg => <<"Health Check Interval out of range">>,
+        min => ?HEALTH_CHECK_INTERVAL_RANGE_MIN,
+        max => ?HEALTH_CHECK_INTERVAL_RANGE_MAX
+    }}.
+
 start_after_created(type) -> boolean();
 start_after_created(desc) -> ?DESC("start_after_created");
 start_after_created(default) -> ?START_AFTER_CREATED_RAW;
@@ -99,8 +119,22 @@ auto_restart_interval(type) -> hoconsc:union([infinity, emqx_schema:duration_ms(
 auto_restart_interval(desc) -> ?DESC("auto_restart_interval");
 auto_restart_interval(default) -> ?AUTO_RESTART_INTERVAL_RAW;
 auto_restart_interval(required) -> false;
+auto_restart_interval(validator) -> fun auto_restart_interval_range/1;
 auto_restart_interval(_) -> undefined.
 
+auto_restart_interval_range(AutoRestartInterval) when
+    is_integer(AutoRestartInterval) andalso
+        AutoRestartInterval >= ?AUTO_RESTART_INTERVAL_RANGE_MIN andalso
+        AutoRestartInterval =< ?AUTO_RESTART_INTERVAL_RANGE_MAX
+->
+    ok;
+auto_restart_interval_range(_AutoRestartInterval) ->
+    {error, #{
+        msg => <<"Auto Restart Interval out of range">>,
+        min => ?AUTO_RESTART_INTERVAL_RANGE_MIN,
+        max => ?AUTO_RESTART_INTERVAL_RANGE_MAX
+    }}.
+
 query_mode(type) -> enum([sync, async]);
 query_mode(desc) -> ?DESC("query_mode");
 query_mode(default) -> async;

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

@@ -0,0 +1 @@
+Validate Health Check Interval and Auto Restart Interval against the range from 1ms to 1 hour.