From bc417a676476229080812595b11c7633e22d19e6 Mon Sep 17 00:00:00 2001 From: firest Date: Thu, 10 Aug 2023 17:52:02 +0800 Subject: [PATCH 1/2] fix(datetime): make sure the epoch is not larger than the maximum supported value --- apps/emqx/src/emqx_datetime.erl | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/apps/emqx/src/emqx_datetime.erl b/apps/emqx/src/emqx_datetime.erl index 60f40130b..70e099af4 100644 --- a/apps/emqx/src/emqx_datetime.erl +++ b/apps/emqx/src/emqx_datetime.erl @@ -38,6 +38,12 @@ -typerefl_from_string({epoch_second/0, ?MODULE, to_epoch_second}). -typerefl_from_string({epoch_millisecond/0, ?MODULE, to_epoch_millisecond}). +%% the maximum value is the SECONDS_FROM_0_TO_10000 in the calendar.erl, +%% here minus SECONDS_PER_DAY to tolerate timezone time offset, +%% so the maximum date can reach 9999-12-31 which is ample. +-define(MAXIMUM_EPOCH, 253402214400). +-define(MAXIMUM_EPOCH_MILLI, 253402214400_000). + to_epoch_second(DateTime) -> to_epoch(DateTime, second). @@ -47,8 +53,7 @@ to_epoch_millisecond(DateTime) -> to_epoch(DateTime, Unit) -> try case string:to_integer(DateTime) of - {Epoch, []} when Epoch >= 0 -> {ok, Epoch}; - {_Epoch, []} -> {error, bad_epoch}; + {Epoch, []} -> validate_epoch(Epoch, Unit); _ -> {ok, calendar:rfc3339_to_system_time(DateTime, [{unit, Unit}])} end catch @@ -71,6 +76,15 @@ human_readable_duration_string(Milliseconds) -> L2 = lists:map(fun({Time, Unit}) -> [integer_to_list(Time), Unit] end, L1), lists:flatten(lists:join(", ", L2)). +validate_epoch(Epoch, _Unit) when Epoch < 0 -> + {error, bad_epoch}; +validate_epoch(Epoch, second) when Epoch =< ?MAXIMUM_EPOCH -> + {ok, Epoch}; +validate_epoch(Epoch, millisecond) when Epoch =< ?MAXIMUM_EPOCH_MILLI -> + {ok, Epoch}; +validate_epoch(_Epoch, _Unit) -> + {error, bad_epoch}. + -ifdef(TEST). -include_lib("eunit/include/eunit.hrl"). -compile(nowarn_export_all). @@ -90,9 +104,11 @@ fields(bar) -> ). epoch_ok_test() -> + BigStamp = 1 bsl 37, Args = [ {0, 0, 0, 0}, {1, 1, 1, 1}, + {BigStamp, BigStamp * 1000, BigStamp, BigStamp * 1000}, {"2022-01-01T08:00:00+08:00", "2022-01-01T08:00:00+08:00", 1640995200, 1640995200000} ], lists:foreach( @@ -112,9 +128,12 @@ check_ok(Input, Sec, Ms) -> ok. epoch_failed_test() -> + BigStamp = 1 bsl 38, Args = [ {-1, -1}, {"1s", "1s"}, + {BigStamp, 0}, + {0, BigStamp * 1000}, {"2022-13-13T08:00:00+08:00", "2022-13-13T08:00:00+08:00"} ], lists:foreach( From 749c2d075fcbbd33937f6826873d43c279815d35 Mon Sep 17 00:00:00 2001 From: firest Date: Thu, 10 Aug 2023 18:28:56 +0800 Subject: [PATCH 2/2] chore: update changes && bump app version --- apps/emqx/src/emqx.app.src | 2 +- changes/ce/fix-11424.en.md | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 changes/ce/fix-11424.en.md diff --git a/apps/emqx/src/emqx.app.src b/apps/emqx/src/emqx.app.src index f324d6ae0..513f88612 100644 --- a/apps/emqx/src/emqx.app.src +++ b/apps/emqx/src/emqx.app.src @@ -2,7 +2,7 @@ {application, emqx, [ {id, "emqx"}, {description, "EMQX Core"}, - {vsn, "5.1.7"}, + {vsn, "5.1.8"}, {modules, []}, {registered, []}, {applications, [ diff --git a/changes/ce/fix-11424.en.md b/changes/ce/fix-11424.en.md new file mode 100644 index 000000000..1d44d9745 --- /dev/null +++ b/changes/ce/fix-11424.en.md @@ -0,0 +1 @@ +Add a check for the maximum value of the timestamp in the API to ensure it is a valid Unix timestamp.