From: Evgeniy Khramtsov Date: Sun, 13 Nov 2016 11:17:21 +0000 (+0300) Subject: Add more control for decoding IQ payloads X-Git-Tag: 16.12-beta1~54 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ebefd0d8d6bd0162f0067f85e565afde83a962ca;p=ejabberd Add more control for decoding IQ payloads --- diff --git a/src/ejabberd_local.erl b/src/ejabberd_local.erl index 210575e5e..d7849396b 100644 --- a/src/ejabberd_local.erl +++ b/src/ejabberd_local.erl @@ -96,13 +96,7 @@ process_iq(From, To, #iq{type = T} = Packet) when T == get; T == set -> Err = xmpp:make_error(Packet, xmpp:err_bad_request()), ejabberd_router:route(To, From, Err); process_iq(From, To, #iq{type = T} = Packet) when T == result; T == error -> - try - NewPacket = xmpp:decode_els(Packet), - process_iq_reply(From, To, NewPacket) - catch _:{xmpp_codec, Why} -> - ?DEBUG("failed to decode iq-result ~p: ~s", - [Packet, xmpp:format_error(Why)]) - end. + process_iq_reply(From, To, Packet). -spec process_iq_reply(jid(), jid(), iq()) -> any(). process_iq_reply(From, To, #iq{id = ID} = IQ) -> diff --git a/src/gen_iq_handler.erl b/src/gen_iq_handler.erl index 8af2cb028..bcbda1d1e 100644 --- a/src/gen_iq_handler.erl +++ b/src/gen_iq_handler.erl @@ -153,11 +153,9 @@ process_iq(_Host, Module, Function, From, To, IQ0) -> -spec process_iq(module(), atom(), iq()) -> ignore | iq(). process_iq(Module, Function, #iq{lang = Lang, sub_els = [El]} = IQ) -> try - %% TODO: move this 'conditional' decoding somewhere - %% IQ handler should know *nothing* about vCards. - Pkt = case xmpp:get_ns(El) of - ?NS_VCARD when Module == mod_vcard -> El; - _ -> xmpp:decode(El) + Pkt = case erlang:function_exported(Module, decode_iq_subel, 1) of + true -> Module:decode_iq_subel(El); + false -> xmpp:decode(El) end, Module:Function(IQ#iq{sub_els = [Pkt]}) catch error:{xmpp_codec, Why} -> diff --git a/src/mod_delegation.erl b/src/mod_delegation.erl index ad57bad44..56908d9d1 100644 --- a/src/mod_delegation.erl +++ b/src/mod_delegation.erl @@ -18,7 +18,7 @@ -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). -export([component_connected/1, component_disconnected/2, - ejabberd_local/1, ejabberd_sm/1, + ejabberd_local/1, ejabberd_sm/1, decode_iq_subel/1, disco_local_features/5, disco_sm_features/5, disco_local_identity/5, disco_sm_identity/5]). @@ -56,6 +56,12 @@ mod_opt_type(_) -> depends(_, _) -> []. +-spec decode_iq_subel(xmpp_element()) -> xmpp_element(); + (xmlel()) -> xmlel(). +%% Tell gen_iq_handler not to auto-decode IQ payload +decode_iq_subel(El) -> + El. + -spec component_connected(binary()) -> ok. component_connected(Host) -> lists:foreach( diff --git a/src/mod_vcard.erl b/src/mod_vcard.erl index 8333d32cf..35b907f95 100644 --- a/src/mod_vcard.erl +++ b/src/mod_vcard.erl @@ -37,7 +37,7 @@ remove_user/2, export/1, import/1, import/3, depends/2, process_search/1, process_vcard/1, get_vcard/2, disco_items/5, disco_features/5, disco_identity/5, - mod_opt_type/1, set_vcard/3, make_vcard_search/4]). + decode_iq_subel/1, mod_opt_type/1, set_vcard/3, make_vcard_search/4]). -include("ejabberd.hrl"). -include("logger.hrl"). @@ -167,6 +167,14 @@ get_sm_features(Acc, _From, _To, Node, _Lang) -> _ -> Acc end. +-spec decode_iq_subel(xmpp_element() | xmlel()) -> xmpp_element() | xmlel(). +%% Tell gen_iq_handler not to decode vcard elements +decode_iq_subel(El) -> + case xmpp:get_ns(El) of + ?NS_VCARD -> xmpp:encode(El); + _ -> xmpp:decode(El) + end. + -spec process_local_iq(iq()) -> iq(). process_local_iq(#iq{type = set, lang = Lang} = IQ) -> Txt = <<"Value 'set' of 'type' attribute is not allowed">>,