Skip to content

Commit

Permalink
Simplify the jid data structure
Browse files Browse the repository at this point in the history
Remove fields that should actually never be used. The idea is that the
non-normalised parts MUST actually have never been used for comparison,
and are therefore not really needed. If only for printing and using them
in the `to` and `from` attributes of a stanza, clients SHOULD also
stringprep anyway, so the fact that the server might provide
non-normalised strings might be a problem for clients who're not
enforced to normalise them.

I've also been verifying how many other XMPP implementations tackle this
issue, and I've seen many other servers, and also a bunch of client
frameworks, simply capturing the parts and normalising them, and
building data structures that keep only their normalised pieces.
  • Loading branch information
NelsonVides committed Feb 3, 2022
1 parent bd28c4a commit a2b09d3
Show file tree
Hide file tree
Showing 4 changed files with 13 additions and 40 deletions.
5 changes: 1 addition & 4 deletions include/jid.hrl
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
-record(jid, {user = <<>> :: jid:user(),
server = <<>> :: jid:server(),
resource = <<>> :: jid:resource(),
luser = <<>> :: jid:luser(),
-record(jid, {luser = <<>> :: jid:luser(),
lserver = <<>> :: jid:lserver(),
lresource = <<>> :: jid:lresource()
}).
Expand Down
28 changes: 9 additions & 19 deletions src/jid.erl
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,7 @@ make(User, Server, Res) ->
{_, error, _} -> error;
{_, _, error} -> error;
{LUser, LServer, LRes} ->
#jid{user = User,
server = Server,
resource = Res,
luser = LUser,
#jid{luser = LUser,
lserver = LServer,
lresource = LRes}
end.
Expand All @@ -95,10 +92,7 @@ make_bare(User, Server) ->
{error, _} -> error;
{_, error} -> error;
{LUser, LServer} ->
#jid{user = User,
server = Server,
resource = <<>>,
luser = LUser,
#jid{luser = LUser,
lserver = LServer,
lresource = <<>>}
end.
Expand All @@ -108,10 +102,7 @@ make_bare(User, Server) ->
Server :: lserver(),
Resource :: lresource()) -> jid().
make_noprep(LUser, LServer, LResource) ->
#jid{user = LUser,
server = LServer,
resource = LResource,
luser = LUser,
#jid{luser = LUser,
lserver = LServer,
lresource = LResource}.

Expand Down Expand Up @@ -157,8 +148,7 @@ from_binary(_) ->
from_binary_noprep(J) when is_binary(J), byte_size(J) < ?XMPP_JID_SIZE_LIMIT ->
case from_binary_nif(J) of
{U, S, R} ->
#jid{user = U, server = S, resource = R,
luser = U, lserver = S, lresource = R};
#jid{luser = U, lserver = S, lresource = R};
error -> error
end;
from_binary_noprep(_) ->
Expand All @@ -185,8 +175,8 @@ to_binary({<<>>, Server}) ->
<<Server/binary>>;
to_binary({Node, Server}) ->
<<Node/binary, "@", Server/binary>>;
to_binary(#jid{user = User, server = Server, resource = Resource}) ->
to_binary({User, Server, Resource});
to_binary(#jid{luser = LUser, lserver = LServer, lresource = LResource}) ->
to_binary({LUser, LServer, LResource});
to_binary(Jid) when is_binary(Jid) ->
Jid.

Expand Down Expand Up @@ -256,7 +246,7 @@ to_lus(error) ->
(jid()) -> jid();
(error) -> error.
to_bare(#jid{} = JID) ->
JID#jid{resource = <<>>, lresource = <<>>};
JID#jid{lresource = <<>>};
to_bare({U, S, _R}) ->
{U, S, <<>>};
to_bare(error) ->
Expand All @@ -268,13 +258,13 @@ replace_resource(#jid{} = JID, Resource) ->
case resourceprep(Resource) of
error -> error;
LResource ->
JID#jid{resource = Resource, lresource = LResource}
JID#jid{lresource = LResource}
end.

%% @doc Replaces the resource part of a jid with a new resource, but without normalisation
-spec replace_resource_noprep(jid(), resource()) -> jid().
replace_resource_noprep(#jid{} = JID, LResource) ->
JID#jid{resource = LResource, lresource = LResource}.
JID#jid{lresource = LResource}.

%% @equiv jid:to_bare(jid:from_binary(BinaryJid))
-spec binary_to_bare(binary()) -> jid() | error.
Expand Down
15 changes: 1 addition & 14 deletions test/jid_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ groups() ->
binary_noprep_to_jid_fails_with_empty_binary,
make_jid_fails_on_binaries_that_are_too_long,
make_is_independent_of_the_input_format,
make_noprep_and_make_have_equal_raw_jid,
make_noprep_is_independent_of_the_input_format,
jid_to_lower_fails_if_any_binary_is_invalid,
jid_replace_resource_failes_for_invalid_resource,
Expand Down Expand Up @@ -98,18 +97,6 @@ make_is_independent_of_the_input_format(_) ->
jid:make(U,S,R) == jid:make({U,S,R})),
run_property(Prop, 100, 1, 500).

make_noprep_and_make_have_equal_raw_jid(_) ->
Prop = ?FORALL({U, S, R},
{jid_gen:username(), jid_gen:domain(), jid_gen:resource()},
begin
#jid{user = U, server = S, resource = R} = jid:make(U, S, R),
#jid{user = U, server = S, resource = R} = jid:make_noprep(U, S, R),
true
end
),
run_property(Prop, 10, 1, 500).


make_noprep_is_independent_of_the_input_format(_) ->
Prop = ?FORALL({U, S, R},
{jid_gen:username(), jid_gen:domain(), jid_gen:resource()},
Expand Down Expand Up @@ -330,7 +317,7 @@ binary_to_jid3(<<>>, N, S, R) ->
to_binary(Jid) when is_binary(Jid) ->
% sometimes it is used to format error messages
Jid;
to_binary(#jid{user = User, server = Server, resource = Resource}) ->
to_binary(#jid{luser = User, lserver = Server, lresource = Resource}) ->
to_binary({User, Server, Resource});
to_binary({User, Server}) ->
to_binary({User, Server, <<>>});
Expand Down
5 changes: 2 additions & 3 deletions test/jid_gen.erl
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,14 @@

jid_struct() ->
?LET({U, S, R}, {username(), domain(), resource()},
{jid, U, S, R, U, S, R}).
{jid, U, S, R}).

from_jid() ->
oneof([
{jid_gen:username(), jid_gen:domain(), jid_gen:resource()},
{<<>>, jid_gen:domain(), jid_gen:resource()},
{jid_gen:username(), jid_gen:domain()},
{jid, jid_gen:username(), jid_gen:domain(), jid_gen:resource(),
jid_gen:username(), jid_gen:domain(), jid_gen:resource()}
{jid, jid_gen:username(), jid_gen:domain(), jid_gen:resource()}
]).

jid() ->
Expand Down

0 comments on commit a2b09d3

Please sign in to comment.