From b8f22ff538da8297b66010912b3fc91e46ded5c0 Mon Sep 17 00:00:00 2001 From: Evgeniy Khramtsov Date: Sun, 13 Nov 2016 10:44:53 +0300 Subject: [PATCH] Deprecate most of the functions from jlib.erl --- specs/xmpp_codec.spec | 4 +- src/ejabberd_oauth.erl | 4 +- src/jlib.erl | 57 +++++++++--- src/mod_admin_extra.erl | 4 +- src/mod_mam.erl | 10 +-- src/mod_muc_admin.erl | 2 +- src/mod_offline.erl | 151 +++++++++++++++++++------------- src/mod_offline_mnesia.erl | 10 ++- src/mod_offline_riak.erl | 9 +- src/mod_offline_sql.erl | 70 ++++++++------- src/prosody2ejabberd.erl | 8 +- src/pubsub_db_sql.erl | 4 +- src/pubsub_subscription.erl | 8 +- src/pubsub_subscription_sql.erl | 8 +- src/randoms.erl | 2 +- src/xmpp.erl | 7 +- src/xmpp_codec.erl | 5 +- src/xmpp_util.erl | 31 +++---- 18 files changed, 230 insertions(+), 164 deletions(-) diff --git a/specs/xmpp_codec.spec b/specs/xmpp_codec.spec index 12bc4b6a9..bcab7a6e5 100644 --- a/specs/xmpp_codec.spec +++ b/specs/xmpp_codec.spec @@ -3471,10 +3471,10 @@ enc_tzo({H, M}) -> -spec dec_utc(_) -> erlang:timestamp(). dec_utc(Val) -> - {_, _, _} = jlib:datetime_string_to_timestamp(Val). + xmpp_util:decode_timestamp(Val). enc_utc(Val) -> - jlib:now_to_utc_string(Val). + xmpp_util:encode_timestamp(Val). -spec dec_jid(_) -> jid:jid(). dec_jid(Val) -> diff --git a/src/ejabberd_oauth.erl b/src/ejabberd_oauth.erl index 318feb3f8..e03b78fe8 100644 --- a/src/ejabberd_oauth.erl +++ b/src/ejabberd_oauth.erl @@ -494,7 +494,7 @@ process(_Handlers, TTL = proplists:get_value(<<"ttl">>, Q, <<"">>), ExpiresIn = case TTL of <<>> -> undefined; - _ -> jlib:binary_to_integer(TTL) + _ -> binary_to_integer(TTL) end, case oauth2:authorize_password({Username, Server}, ClientId, @@ -556,7 +556,7 @@ process(_Handlers, TTL = proplists:get_value(<<"ttl">>, Q, <<"">>), ExpiresIn = case TTL of <<>> -> undefined; - _ -> jlib:binary_to_integer(TTL) + _ -> binary_to_integer(TTL) end, case oauth2:authorize_password({Username, Server}, Scope, diff --git a/src/jlib.erl b/src/jlib.erl index aca3b0ee8..f7dbebd86 100644 --- a/src/jlib.erl +++ b/src/jlib.erl @@ -35,27 +35,33 @@ binary_to_integer/1, integer_to_binary/1]}). +-export([tolower/1, term_to_base64/1, base64_to_term/1, + decode_base64/1, encode_base64/1, ip_to_list/1, + atom_to_binary/1, binary_to_atom/1, tuple_to_binary/1, + l2i/1, i2l/1, i2l/2, queue_drop_while/2, + expr_to_term/1, term_to_expr/1]). + +%% The following functions are used by gen_iq_handler.erl for providing backward +%% compatibility and must not be used in other parts of the code +%% Use xmpp:decode() and xmpp:encode() instead +-export([iq_query_info/1, iq_to_xml/1]). + +%% The following functions are deprecated and will be removed soon +%% Use functions from xmpp.erl and xmpp_util.erl instead -export([make_result_iq_reply/1, make_error_reply/3, make_error_reply/2, make_error_element/2, make_correct_from_to_attrs/3, replace_from_to_attrs/3, replace_from_to/3, replace_from_attrs/2, replace_from/2, - remove_attr/2, tolower/1, - get_iq_namespace/1, iq_query_info/1, + remove_attr/2, get_iq_namespace/1, iq_query_or_response_info/1, is_iq_request_type/1, - iq_to_xml/1, parse_xdata_submit/1, - unwrap_carbon/1, is_standalone_chat_state/1, + parse_xdata_submit/1, unwrap_carbon/1, is_standalone_chat_state/1, add_delay_info/3, add_delay_info/4, timestamp_to_legacy/1, timestamp_to_iso_basic/1, timestamp_to_iso/2, now_to_utc_string/1, now_to_local_string/1, datetime_string_to_timestamp/1, - term_to_base64/1, base64_to_term/1, - decode_base64/1, encode_base64/1, ip_to_list/1, rsm_encode/1, rsm_encode/2, rsm_decode/1, binary_to_integer/1, binary_to_integer/2, - integer_to_binary/1, integer_to_binary/2, - atom_to_binary/1, binary_to_atom/1, tuple_to_binary/1, - l2i/1, i2l/1, i2l/2, queue_drop_while/2, - expr_to_term/1, term_to_expr/1]). + integer_to_binary/1, integer_to_binary/2]). %% The following functions are deprecated and will be removed soon %% Use corresponding functions from jid.erl instead @@ -75,8 +81,37 @@ {jid_tolower, 1}, {jid_remove_resource, 1}, {jid_replace_resource, 2}, + {add_delay_info, 3}, + {add_delay_info, 4}, + {make_result_iq_reply, 1}, + {make_error_reply, 3}, + {make_error_reply, 2}, + {make_error_element, 2}, + {make_correct_from_to_attrs, 3}, + {replace_from_to_attrs, 3}, + {replace_from_to, 3}, + {replace_from_attrs, 2}, + {replace_from, 2}, + {remove_attr, 2}, + {get_iq_namespace, 1}, + {iq_query_or_response_info, 1}, + {is_iq_request_type, 1}, + {parse_xdata_submit, 1}, + {unwrap_carbon, 1}, + {is_standalone_chat_state, 1}, + {timestamp_to_legacy, 1}, + {timestamp_to_iso_basic, 1}, + {timestamp_to_iso, 2}, + {now_to_utc_string, 1}, + {now_to_local_string, 1}, + {datetime_string_to_timestamp, 1}, + {rsm_encode, 1}, + {rsm_encode, 2}, + {rsm_decode, 1}, + {binary_to_integer, 1}, + {binary_to_integer, 2}, {integer_to_binary, 1}, - {binary_to_integer, 1}]). + {integer_to_binary, 2}]). -include("ejabberd.hrl"). -include("jlib.hrl"). diff --git a/src/mod_admin_extra.erl b/src/mod_admin_extra.erl index 69fffbd7c..2967e86a0 100644 --- a/src/mod_admin_extra.erl +++ b/src/mod_admin_extra.erl @@ -761,7 +761,9 @@ set_random_password(User, Server, Reason) -> set_password_auth(User, Server, NewPass). build_random_password(Reason) -> - Date = jlib:timestamp_to_legacy(calendar:universal_time()), + {{Year, Month, Day}, {Hour, Minute, Second}} = calendar:universal_time(), + Date = str:format("~4..0B~2..0B~2..0BT~2..0B:~2..0B:~2..0B", + [Year, Month, Day, Hour, Minute, Second]), RandomString = randoms:get_string(), <<"BANNED_ACCOUNT--", Date/binary, "--", RandomString/binary, "--", Reason/binary>>. diff --git a/src/mod_mam.erl b/src/mod_mam.erl index 3d5c8f64d..8c5422f07 100644 --- a/src/mod_mam.erl +++ b/src/mod_mam.erl @@ -312,14 +312,14 @@ parse_query(#mam_query{xdata = #xdata{fields = Fs}} = Query, Lang) -> try lists:foldl( fun(#xdata_field{var = <<"start">>, values = [Data|_]}, Q) -> - case jlib:datetime_string_to_timestamp(Data) of - undefined -> throw({error, <<"start">>}); + try xmpp_util:decode_timestamp(Data) of {_, _, _} = TS -> Q#mam_query{start = TS} + catch _:{bad_timestamp, _} -> throw({error, <<"start">>}) end; (#xdata_field{var = <<"end">>, values = [Data|_]}, Q) -> - case jlib:datetime_string_to_timestamp(Data) of - undefined -> throw({error, <<"end">>}); - {_, _, _} = TS -> Q#mam_query{'end' = TS} + try xmpp_util:decode_timestamp(Data) of + {_, _, _} = TS -> Q#mam_query{start = TS} + catch _:{bad_timestamp, _} -> throw({error, <<"end">>}) end; (#xdata_field{var = <<"with">>, values = [Data|_]}, Q) -> case jid:from_string(Data) of diff --git a/src/mod_muc_admin.erl b/src/mod_muc_admin.erl index 8f1f649d2..91ccce559 100644 --- a/src/mod_muc_admin.erl +++ b/src/mod_muc_admin.erl @@ -388,7 +388,7 @@ build_info_room({Name, Host, Pid}) -> false -> Last_message1 = queue:last(History), {_, _, _, Ts_last, _} = Last_message1, - jlib:timestamp_to_legacy(Ts_last) + xmpp_util:encode_timestamp(Ts_last) end, {<>, diff --git a/src/mod_offline.erl b/src/mod_offline.erl index dfe3c9e8e..2f6d52c36 100644 --- a/src/mod_offline.erl +++ b/src/mod_offline.erl @@ -285,7 +285,7 @@ get_sm_items(_Acc, #jid{luser = U, lserver = S, lresource = R} = JID, BareJID = jid:remove_resource(JID), Pid ! dont_ask_offline, {result, lists:map( - fun({Seq, From, _To, _El}) -> + fun({Seq, From, _To, _TS, _El}) -> Node = integer_to_binary(Seq), #disco_item{jid = BareJID, node = Node, @@ -400,10 +400,10 @@ handle_offline_fetch(#jid{luser = U, lserver = S, lresource = R}) -> Pid when is_pid(Pid) -> Pid ! dont_ask_offline, lists:foreach( - fun({Node, From, To, El}) -> + fun({Node, El}) -> NewEl = set_offline_tag(El, Node), - Pid ! {route, From, To, NewEl} - end, read_message_headers(U, S)) + Pid ! {route, xmpp:get_from(El), xmpp:get_to(El), NewEl} + end, read_messages(U, S)) end. -spec fetch_msg_by_node(jid(), binary()) -> error | {ok, #offline_msg{}}. @@ -476,11 +476,13 @@ store_packet(From, To, Packet) -> NewPacket -> TimeStamp = p1_time_compat:timestamp(), Expire = find_x_expire(TimeStamp, NewPacket), - El = xmpp:encode(NewPacket), gen_mod:get_module_proc(To#jid.lserver, ?PROCNAME) ! #offline_msg{us = {LUser, LServer}, - timestamp = TimeStamp, expire = Expire, - from = From, to = To, packet = El}, + timestamp = TimeStamp, + expire = Expire, + from = From, + to = To, + packet = NewPacket}, stop end; _ -> ok @@ -547,10 +549,13 @@ resend_offline_messages(User, Server) -> Mod = gen_mod:db_mod(LServer, ?MODULE), case Mod:pop_messages(LUser, LServer) of {ok, Rs} -> - lists:foreach(fun (R) -> - ejabberd_sm ! offline_msg_to_route(LServer, R) - end, - lists:keysort(#offline_msg.timestamp, Rs)); + lists:foreach( + fun(R) -> + case offline_msg_to_route(LServer, R) of + error -> ok; + RouteMsg -> ejabberd_sm ! RouteMsg + end + end, lists:keysort(#offline_msg.timestamp, Rs)); _ -> ok end. @@ -565,22 +570,26 @@ pop_offline_messages(Ls, User, Server) -> {ok, Rs} -> TS = p1_time_compat:timestamp(), Ls ++ - lists:map(fun (R) -> - offline_msg_to_route(LServer, R) - end, - lists:filter( - fun(#offline_msg{packet = Pkt} = R) -> - Expire = case R#offline_msg.expire of - undefined -> - find_x_expire(TS, Pkt); - Exp -> - Exp - end, - case Expire of - never -> true; - TimeStamp -> TS < TimeStamp - end - end, Rs)); + lists:flatmap( + fun(R) -> + case offline_msg_to_route(LServer, R) of + error -> []; + RouteMsg -> [RouteMsg] + end + end, + lists:filter( + fun(#offline_msg{packet = Pkt} = R) -> + Expire = case R#offline_msg.expire of + undefined -> + find_x_expire(TS, Pkt); + Exp -> + Exp + end, + case Expire of + never -> true; + TimeStamp -> TS < TimeStamp + end + end, Rs)); _ -> Ls end. @@ -625,52 +634,61 @@ webadmin_page(_, Host, webadmin_page(Acc, _, _) -> Acc. get_offline_els(LUser, LServer) -> - Hdrs = read_message_headers(LUser, LServer), - lists:map( - fun({_Seq, From, To, Packet}) -> - xmpp:set_from_to(Packet, From, To) - end, Hdrs). + [Packet || {_Seq, Packet} <- read_messages(LUser, LServer)]. +-spec offline_msg_to_route(binary(), #offline_msg{}) -> + {route, jid(), jid(), message()} | error. offline_msg_to_route(LServer, #offline_msg{} = R) -> - Pkt = xmpp:decode(R#offline_msg.packet, ?NS_CLIENT, [ignore_els]), - Pkt1 = case R#offline_msg.timestamp of - undefined -> - Pkt; - TS -> - xmpp_util:add_delay_info(Pkt, jid:make(LServer), TS, - <<"Offline Storage">>) - end, - {route, R#offline_msg.from, R#offline_msg.to, Pkt1}. - -read_message_headers(LUser, LServer) -> + try xmpp:decode(R#offline_msg.packet, ?NS_CLIENT, [ignore_els]) of + Pkt -> + NewPkt = add_delay_info(Pkt, LServer, R#offline_msg.timestamp), + {route, R#offline_msg.from, R#offline_msg.to, NewPkt} + catch _:{xmpp_codec, Why} -> + ?ERROR_MSG("failed to decode packet ~p of user ~s: ~s", + [R#offline_msg.packet, jid:to_string(R#offline_msg.to), + xmpp:format_error(Why)]), + error + end. + +-spec read_messages(binary(), binary()) -> [{binary(), message()}]. +read_messages(LUser, LServer) -> Mod = gen_mod:db_mod(LServer, ?MODULE), - lists:map( - fun({Seq, From, To, El}) -> + lists:flatmap( + fun({Seq, From, To, TS, El}) -> Node = integer_to_binary(Seq), - Packet = xmpp:decode(El, ?NS_CLIENT, [ignore_els]), - {Node, From, To, Packet} + try xmpp:decode(El, ?NS_CLIENT, [ignore_els]) of + Pkt -> + Node = integer_to_binary(Seq), + Pkt1 = add_delay_info(Pkt, LServer, TS), + Pkt2 = xmpp:set_from_to(Pkt1, From, To), + [{Node, Pkt2}] + catch _:{xmpp_codec, Why} -> + ?ERROR_MSG("failed to decode packet ~p " + "of user ~s: ~s", + [El, jid:to_string(To), + xmpp:format_error(Why)]), + [] + end end, Mod:read_message_headers(LUser, LServer)). format_user_queue(Hdrs) -> lists:map( - fun({Seq, From, To, El}) -> + fun({Seq, From, To, TS, El}) -> ID = integer_to_binary(Seq), FPacket = ejabberd_web_admin:pretty_print_xml(El), SFrom = jid:to_string(From), STo = jid:to_string(To), - Stamp = fxml:get_path_s(El, [{elem, <<"delay">>}, - {attr, <<"stamp">>}]), - Time = case jlib:datetime_string_to_timestamp(Stamp) of + Time = case TS of + undefined -> + Stamp = fxml:get_path_s(El, [{elem, <<"delay">>}, + {attr, <<"stamp">>}]), + try xmpp_util:decode_timestamp(Stamp) of + {_, _, _} = Now -> format_time(Now) + catch _:_ -> + <<"">> + end; {_, _, _} = Now -> - {{Year, Month, Day}, {Hour, Minute, Second}} = - calendar:now_to_local_time(Now), - iolist_to_binary( - io_lib:format( - "~w-~.2.0w-~.2.0w ~.2.0w:~.2.0w:~.2.0w", - [Year, Month, Day, Hour, Minute, - Second])); - _ -> - <<"">> + format_time(Now) end, ?XE(<<"tr">>, [?XAE(<<"td">>, [{<<"class">>, <<"valign">>}], @@ -682,6 +700,11 @@ format_user_queue(Hdrs) -> [?XC(<<"pre">>, FPacket)])]) end, Hdrs). +format_time(Now) -> + {{Year, Month, Day}, {Hour, Minute, Second}} = calendar:now_to_local_time(Now), + str:format("~w-~.2.0w-~.2.0w ~.2.0w:~.2.0w:~.2.0w", + [Year, Month, Day, Hour, Minute, Second]). + user_queue(User, Server, Query, Lang) -> LUser = jid:nodeprep(User), LServer = jid:nameprep(Server), @@ -815,6 +838,14 @@ count_offline_messages(User, Server) -> Mod = gen_mod:db_mod(LServer, ?MODULE), Mod:count_messages(LUser, LServer). +-spec add_delay_info(message(), binary(), + undefined | erlang:timestamp()) -> message(). +add_delay_info(Packet, _LServer, undefined) -> + Packet; +add_delay_info(Packet, LServer, {_, _, _} = TS) -> + xmpp_util:add_delay_info(Packet, jid:make(LServer), TS, + <<"Offline storage">>). + export(LServer) -> Mod = gen_mod:db_mod(LServer, ?MODULE), Mod:export(LServer). diff --git a/src/mod_offline_mnesia.erl b/src/mod_offline_mnesia.erl index c9f088fa4..9fec9c4d5 100644 --- a/src/mod_offline_mnesia.erl +++ b/src/mod_offline_mnesia.erl @@ -42,7 +42,11 @@ store_messages(_Host, US, Msgs, Len, MaxOfflineMsgs) -> mnesia:write_lock_table(offline_msg); true -> ok end, - lists:foreach(fun (M) -> mnesia:write(M) end, Msgs) + lists:foreach( + fun(#offline_msg{packet = Pkt} = M) -> + El = xmpp:encode(Pkt), + mnesia:write(M#offline_msg{packet = El}) + end, Msgs) end end, mnesia:transaction(F). @@ -107,9 +111,7 @@ read_message_headers(LUser, LServer) -> fun(#offline_msg{from = From, to = To, packet = Pkt, timestamp = TS}) -> Seq = now_to_integer(TS), - NewPkt = jlib:add_delay_info(Pkt, LServer, TS, - <<"Offline Storage">>), - {Seq, From, To, NewPkt} + {Seq, From, To, TS, Pkt} end, Msgs), lists:keysort(1, Hdrs). diff --git a/src/mod_offline_riak.erl b/src/mod_offline_riak.erl index 647f71dfd..241a8d650 100644 --- a/src/mod_offline_riak.erl +++ b/src/mod_offline_riak.erl @@ -36,9 +36,12 @@ store_messages(Host, {User, _}, Msgs, Len, MaxOfflineMsgs) -> try lists:foreach( fun(#offline_msg{us = US, + packet = Pkt, timestamp = TS} = M) -> + El = xmpp:encode(Pkt), ok = ejabberd_riak:put( - M, offline_msg_schema(), + M#offline_msg{packet = El}, + offline_msg_schema(), [{i, TS}, {'2i', [{<<"us">>, US}]}]) end, Msgs), {atomic, ok} @@ -85,9 +88,7 @@ read_message_headers(LUser, LServer) -> fun(#offline_msg{from = From, to = To, packet = Pkt, timestamp = TS}) -> Seq = now_to_integer(TS), - NewPkt = jlib:add_delay_info( - Pkt, LServer, TS, <<"Offline Storage">>), - {Seq, From, To, NewPkt} + {Seq, From, To, Pkt} end, Rs), lists:keysort(1, Hdrs); _Err -> diff --git a/src/mod_offline_sql.erl b/src/mod_offline_sql.erl index 9459753bc..2b7a40bff 100644 --- a/src/mod_offline_sql.erl +++ b/src/mod_offline_sql.erl @@ -41,14 +41,14 @@ store_messages(Host, {User, _Server}, Msgs, Len, MaxOfflineMsgs) -> LUser = (M#offline_msg.to)#jid.luser, From = M#offline_msg.from, To = M#offline_msg.to, - Packet = - jlib:replace_from_to(From, To, - M#offline_msg.packet), - NewPacket = - jlib:add_delay_info(Packet, Host, - M#offline_msg.timestamp, - <<"Offline Storage">>), - XML = fxml:element_to_binary(NewPacket), + Packet = xmpp:set_from_to( + M#offline_msg.packet, From, To), + NewPacket = xmpp_util:add_delay_info( + Packet, jid:make(Host), + M#offline_msg.timestamp, + <<"Offline Storage">>), + XML = fxml:element_to_binary( + xmpp:encode(NewPacket)), sql_queries:add_spool_sql(LUser, XML) end, Msgs), @@ -171,15 +171,23 @@ export(_Server) -> [{offline_msg, fun(Host, #offline_msg{us = {LUser, LServer}, timestamp = TimeStamp, from = From, to = To, - packet = Packet}) + packet = El}) when LServer == Host -> - Packet1 = jlib:replace_from_to(From, To, Packet), - Packet2 = jlib:add_delay_info(Packet1, LServer, TimeStamp, - <<"Offline Storage">>), - XML = fxml:element_to_binary(Packet2), - [?SQL("delete from spool where username=%(LUser)s;"), - ?SQL("insert into spool(username, xml) values (" - "%(LUser)s, %(XML)s);")]; + try xmpp:decode(El, ?NS_CLIENT, [ignore_els]) of + Packet -> + Packet1 = xmpp:set_from_to(Packet, From, To), + Packet2 = xmpp_util:add_delay_info( + Packet1, jid:make(LServer), + TimeStamp, <<"Offline Storage">>), + XML = fxml:element_to_binary(xmpp:encode(Packet2)), + [?SQL("delete from spool where username=%(LUser)s;"), + ?SQL("insert into spool(username, xml) values (" + "%(LUser)s, %(XML)s);")] + catch _:{xmpp_codec, Why} -> + ?ERROR_MSG("failed to decode packet ~p of user ~s@~s: ~s", + [El, LUser, LServer, xmpp:format_error(Why)]), + [] + end; (_Host, _R) -> [] end}]. @@ -188,23 +196,21 @@ import(LServer) -> [{<<"select username, xml from spool;">>, fun([LUser, XML]) -> El = #xmlel{} = fxml_stream:parse_element(XML), - From = #jid{} = jid:from_string( - fxml:get_attr_s(<<"from">>, El#xmlel.attrs)), - To = #jid{} = jid:from_string( - fxml:get_attr_s(<<"to">>, El#xmlel.attrs)), - Stamp = fxml:get_path_s(El, [{elem, <<"delay">>}, - {attr, <<"stamp">>}]), - TS = case jlib:datetime_string_to_timestamp(Stamp) of - {_, _, _} = Now -> - Now; - undefined -> - p1_time_compat:timestamp() - end, - Expire = mod_offline:find_x_expire(TS, El#xmlel.children), - #offline_msg{us = {LUser, LServer}, - from = From, to = To, + #message{} = Pkt = xmpp:decode(El, ?NS_CLIENT, [ignore_els]), + From = Pkt#message.from, + To = case Pkt#message.to of + undefined -> jid:make(LUser, LServer); + JID -> JID + end, + TS = case xmpp:get_subtag(Pkt, #delay{}) of + #delay{stamp = Stamp} -> Stamp; + false -> p1_time_compat:timestamp() + end, + Expire = mod_offline:find_x_expire(TS, Pkt), + #offline_msg{us = {LUser, LServer}, + from = From, to = To, packet = El, - timestamp = TS, expire = Expire} + timestamp = TS, expire = Expire} end}]. import(_, _) -> diff --git a/src/prosody2ejabberd.erl b/src/prosody2ejabberd.erl index d5eca5ecb..fcc472dce 100644 --- a/src/prosody2ejabberd.erl +++ b/src/prosody2ejabberd.erl @@ -300,8 +300,8 @@ convert_privacy_item({_, Item}) -> match_presence_out = MatchPresOut}. el_to_offline_msg(LUser, LServer, #xmlel{attrs = Attrs} = El) -> - case jlib:datetime_string_to_timestamp( - fxml:get_attr_s(<<"stamp">>, Attrs)) of + try xmpp_util:decode_timestamp( + fxml:get_attr_s(<<"stamp">>, Attrs)) of {_, _, _} = TS -> Attrs1 = lists:filter( fun(<<"stamp">>) -> false; @@ -321,8 +321,8 @@ el_to_offline_msg(LUser, LServer, #xmlel{attrs = Attrs} = El) -> packet = Packet}]; _ -> [] - end; - _ -> + end + catch _:{bad_timestamp, _} -> [] end. diff --git a/src/pubsub_db_sql.erl b/src/pubsub_db_sql.erl index 69b476539..713d33970 100644 --- a/src/pubsub_db_sql.erl +++ b/src/pubsub_db_sql.erl @@ -132,10 +132,10 @@ integer_to_sql(N) -> iolist_to_binary(integer_to_list(N)). boolean_to_sql(true) -> <<"1">>; boolean_to_sql(false) -> <<"0">>. -timestamp_to_sql(T) -> jlib:now_to_utc_string(T). +timestamp_to_sql(T) -> xmpp_util:encode_timestamp(T). sql_to_integer(N) -> binary_to_integer(N). sql_to_boolean(B) -> B == <<"1">>. -sql_to_timestamp(T) -> jlib:datetime_string_to_timestamp(T). +sql_to_timestamp(T) -> xmpp_util:decode_timestamp(T). diff --git a/src/pubsub_subscription.erl b/src/pubsub_subscription.erl index de1a363db..f2c962257 100644 --- a/src/pubsub_subscription.erl +++ b/src/pubsub_subscription.erl @@ -211,13 +211,11 @@ val_xfield(digest_frequency = Opt, [Val]) -> {error, xmpp:err_not_acceptable(ErrTxt, ?MYLANG)} end; val_xfield(expire = Opt, [Val]) -> - case jlib:datetime_string_to_timestamp(Val) of - undefined -> + try xmpp_util:decode_timestamp(Val) + catch _:{bad_timestamp, _} -> Txt = <<"Value of '~s' should be datetime string">>, ErrTxt = iolist_to_binary(io_lib:format(Txt, [Opt])), - {error, xmpp:err_not_acceptable(ErrTxt, ?MYLANG)}; - Timestamp -> - Timestamp + {error, xmpp:err_not_acceptable(ErrTxt, ?MYLANG)} end; val_xfield(include_body = Opt, [Val]) -> xopt_to_bool(Opt, Val); val_xfield(show_values, Vals) -> Vals; diff --git a/src/pubsub_subscription_sql.erl b/src/pubsub_subscription_sql.erl index 32aa41a93..922b2a418 100644 --- a/src/pubsub_subscription_sql.erl +++ b/src/pubsub_subscription_sql.erl @@ -176,13 +176,11 @@ val_xfield(digest_frequency = Opt, [Val]) -> {error, xmpp:err_not_acceptable(ErrTxt, ?MYLANG)} end; val_xfield(expire = Opt, [Val]) -> - case jlib:datetime_string_to_timestamp(Val) of - undefined -> + try xmpp_util:decode_timestamp(Val) + catch _:{bad_timestamp, _} -> Txt = <<"Value of '~s' should be datetime string">>, ErrTxt = iolist_to_binary(io_lib:format(Txt, [Opt])), - {error, xmpp:err_not_acceptable(ErrTxt, ?MYLANG)}; - Timestamp -> - Timestamp + {error, xmpp:err_not_acceptable(ErrTxt, ?MYLANG)} end; val_xfield(include_body = Opt, [Val]) -> xopt_to_bool(Opt, Val); val_xfield(show_values, Vals) -> Vals; diff --git a/src/randoms.erl b/src/randoms.erl index 1353f48af..ae477d27d 100644 --- a/src/randoms.erl +++ b/src/randoms.erl @@ -38,7 +38,7 @@ start() -> get_string() -> R = crypto:rand_uniform(0, ?THRESHOLD), - jlib:integer_to_binary(R). + integer_to_binary(R). uniform() -> crypto:rand_uniform(0, ?THRESHOLD)/?THRESHOLD. diff --git a/src/xmpp.erl b/src/xmpp.erl index 0abcda7ee..2c08c2bcd 100644 --- a/src/xmpp.erl +++ b/src/xmpp.erl @@ -18,7 +18,7 @@ format_error/1, is_stanza/1, set_subtag/2, get_subtag/2, remove_subtag/2, has_subtag/2, decode_els/1, decode_els/3, pp/1, get_name/1, get_text/1, mk_text/1, mk_text/2, - is_known_tag/1, is_known_tag/2]). + is_known_tag/1, is_known_tag/2, append_subtags/2]). %% XMPP errors -export([err_bad_request/0, err_bad_request/2, @@ -369,6 +369,11 @@ has_subtag([El|Els], TagName, XMLNS) -> has_subtag([], _, _) -> false. +-spec append_subtags(stanza(), [xmpp_element() | xmlel()]) -> stanza(). +append_subtags(Stanza, Tags) -> + Els = get_els(Stanza), + set_els(Stanza, Els ++ Tags). + -spec get_text([text()]) -> binary(). get_text([]) -> <<"">>; get_text([#text{data = Data}|_]) -> Data. diff --git a/src/xmpp_codec.erl b/src/xmpp_codec.erl index 8713365cc..2931baaa4 100644 --- a/src/xmpp_codec.erl +++ b/src/xmpp_codec.erl @@ -6782,10 +6782,9 @@ dec_jid(Val) -> J -> J end. -enc_utc(Val) -> jlib:now_to_utc_string(Val). +enc_utc(Val) -> xmpp_util:encode_timestamp(Val). -dec_utc(Val) -> - {_, _, _} = jlib:datetime_string_to_timestamp(Val). +dec_utc(Val) -> xmpp_util:decode_timestamp(Val). enc_tzo({H, M}) -> Sign = if H >= 0 -> <<>>; diff --git a/src/xmpp_util.erl b/src/xmpp_util.erl index 7b3e0e892..a07dae78b 100644 --- a/src/xmpp_util.erl +++ b/src/xmpp_util.erl @@ -27,28 +27,17 @@ add_delay_info(Stz, From, Time) -> erlang:timestamp(), binary()) -> stanza(). add_delay_info(Stz, From, Time, Desc) -> + NewDelay = #delay{stamp = Time, from = From, desc = Desc}, case xmpp:get_subtag(Stz, #delay{}) of - #delay{from = OldFrom, desc = OldDesc} = Delay -> + #delay{from = OldFrom} -> case jid:tolower(From) == jid:tolower(OldFrom) of - true when Desc == <<"">> -> - Stz; - true when OldDesc == <<"">> -> - xmpp:set_subtag(Stz, Delay#delay{desc = Desc}); - true -> - case binary:match(OldDesc, Desc) of - nomatch -> - NewDesc = <>, - xmpp:set_subtag(Stz, Delay#delay{desc = NewDesc}); - _ -> - Stz - end; false -> - NewDelay = #delay{stamp = Time, from = From, desc = Desc}, - xmpp:set_subtag(Stz, NewDelay) + xmpp:set_subtag(Stz, NewDelay); + true -> + xmpp:append_subtags(Stz, [NewDelay]) end; false -> - Delay = #delay{stamp = Time, from = From, desc = Desc}, - xmpp:set_subtag(Stz, Delay) + xmpp:append_subtags(Stz, [NewDelay]) end. -spec unwrap_carbon(stanza()) -> xmpp_element(). @@ -147,10 +136,10 @@ try_decode_timestamp(<>). try_decode_fraction(<<$., T/binary>>) -> - {match, [V]} = re:run(T, <<"^[0-9]+">>, [{capture, [0], binary}]), - Size = size(V), - <> = T, - {to_integer(binary:part(V, 0, min(6, Size)), 0, 999999), + {match, [V]} = re:run(T, <<"^[0-9]+">>, [{capture, [0], list}]), + Size = length(V), + <<_:Size/binary, TZD/binary>> = T, + {list_to_integer(string:left(V, 6, $0)), try_decode_tzd(TZD)}; try_decode_fraction(TZD) -> {0, try_decode_tzd(TZD)}. -- 2.40.0