Skip to content

Commit 88df24e

Browse files
author
Andreas Schultz
committed
validate options before passing the to the socket process
This allows us to throw badarg errors instead of crashing the socket process.
1 parent 3757df7 commit 88df24e

File tree

3 files changed

+51
-23
lines changed

3 files changed

+51
-23
lines changed

src/ezmq.erl

+39-11
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,11 @@
4949
%% @end
5050
%%--------------------------------------------------------------------
5151

52-
start_link(Opts) when is_list(Opts) ->
52+
start_link(RawOpts) when is_list(RawOpts) ->
53+
Opts = lists:map(fun validate_opts/1, proplists:unfold(RawOpts)),
5354
gen_server:start_link(?MODULE, {self(), Opts}, [?SERVER_OPTS]).
54-
start(Opts) when is_list(Opts) ->
55+
start(RawOpts) when is_list(RawOpts) ->
56+
Opts = lists:map(fun validate_opts/1, proplists:unfold(RawOpts)),
5557
gen_server:start(?MODULE, {self(), Opts}, [?SERVER_OPTS]).
5658

5759
socket_link(Opts) when is_list(Opts) ->
@@ -93,7 +95,8 @@ recv(Socket) ->
9395
recv(Socket, Timeout) ->
9496
gen_server:call(Socket, {recv, Timeout}, infinity).
9597

96-
setopts(Socket, Opts) ->
98+
setopts(Socket, RawOpts) ->
99+
Opts = lists:map(fun validate_opts/1, proplists:unfold(RawOpts)),
97100
gen_server:call(Socket, {setopts, Opts}).
98101

99102
sockname(Socket) ->
@@ -227,7 +230,7 @@ init_socket(Owner, Type, Opts) ->
227230
process_flag(trap_exit, true),
228231
MqSState0 = #ezmq_socket{owner = Owner, mode = passive, recv_q = orddict:new(),
229232
connecting = orddict:new(), listen_trans = orddict:new(), transports = [], remote_ids = orddict:new()},
230-
MqSState1 = lists:foldl(fun do_setopts/2, MqSState0, proplists:unfold(Opts)),
233+
MqSState1 = lists:foldl(fun do_setopts/2, MqSState0, Opts),
231234
ezmq_socket_fsm:init(Type, Opts, MqSState1).
232235

233236
%%--------------------------------------------------------------------
@@ -307,7 +310,7 @@ handle_call({send, Msg}, From, State) ->
307310
end;
308311

309312
handle_call({setopts, Opts}, _From, State) ->
310-
NewState = lists:foldl(fun do_setopts/2, State, proplists:unfold(Opts)),
313+
NewState = lists:foldl(fun do_setopts/2, State, Opts),
311314
{reply, ok, NewState};
312315

313316
handle_call(sockname, _From, #ezmq_socket{listen_trans = ListenTrans, transports = Transports} = State) ->
@@ -653,25 +656,50 @@ do_dequeue(Transport, Q) ->
653656
do_setopts({type, Type}, MqSState) ->
654657
MqSState#ezmq_socket{type = Type};
655658
do_setopts({identity, Id}, MqSState) ->
656-
MqSState#ezmq_socket{identity = iolist_to_binary(Id)};
659+
MqSState#ezmq_socket{identity = Id};
657660
do_setopts({active, once}, MqSState) ->
658661
run_recv_q(MqSState#ezmq_socket{mode = active_once});
659662
do_setopts({active, true}, MqSState) ->
660663
run_recv_q(MqSState#ezmq_socket{mode = active});
661664
do_setopts({active, false}, MqSState) ->
662665
MqSState#ezmq_socket{mode = passive};
663-
do_setopts({need_events, NeedEvents}, MqSState) when is_boolean(NeedEvents) ->
666+
do_setopts({need_events, NeedEvents}, MqSState) ->
664667
MqSState#ezmq_socket{need_events = NeedEvents};
665668
do_setopts({version, Version}, MqSState) ->
669+
MqSState#ezmq_socket{version = Version};
670+
671+
do_setopts(_, MqSState) ->
672+
MqSState.
673+
674+
validate_opts(Opt = {type, Type})
675+
when Type == req; Type == rep;
676+
Type == dealer; Type == router;
677+
Type == pub; Type == sub ->
678+
Opt;
679+
680+
validate_opts(Opt = {identity, Id}) when is_binary(Id) ->
681+
Opt;
682+
validate_opts({identity, Id}) when is_list(Id) ->
683+
{identity, iolist_to_binary(Id)};
684+
685+
validate_opts(Opt = {active, once}) -> Opt;
686+
validate_opts(Opt = {active, true}) -> Opt;
687+
validate_opts(Opt = {active, false}) -> Opt;
688+
689+
validate_opts(Opt = {need_events, NeedEvents}) when is_boolean(NeedEvents) ->
690+
Opt;
691+
692+
validate_opts(Opt = {version, Version}) ->
666693
case lists:member(Version, ?SUPPORTED_VERSIONS) of
667694
true ->
668-
MqSState#ezmq_socket{version = Version};
695+
Opt;
669696
_ ->
670-
erlang:error(badargs, [{version, Version}])
697+
erlang:error(badargs, [Opt])
671698
end;
672699

673-
do_setopts(_, MqSState) ->
674-
MqSState.
700+
validate_opts(Opt) ->
701+
erlang:error(badarg, [Opt]).
702+
675703

676704
do_sockname(Transport, _Opts, Acc) ->
677705
case ezmq_tcp_socket:sockname(Transport) of

test/ezmq_SUITE.erl

+5-5
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,13 @@ req_tcp_connect_close(Config) ->
2828
TcpOpts = tcp_opts(Config),
2929
IP = proplists:get_value(localhost, Config, {127,0,0,1}),
3030
{ok, S} = ezmq_client_socket([{type, req}, {active, false}]),
31-
ok = ezmq:connect(S, tcp, IP, 5555, [TcpOpts]),
31+
ok = ezmq:connect(S, tcp, IP, 5555, TcpOpts),
3232
ezmq:close(S).
3333

3434
req_tcp_connect_fail(Config) ->
3535
TcpOpts = tcp_opts(Config),
36-
{ok, S} = ezmq_client_socket([{type, req}, {active, false}|TcpOpts]),
37-
{error,nxdomain} = ezmq:connect(S, tcp, "undefined.undefined", 5555, []),
36+
{ok, S} = ezmq_client_socket([{type, req}, {active, false}]),
37+
{error,nxdomain} = ezmq:connect(S, tcp, "undefined.undefined", 5555, TcpOpts),
3838
ezmq:close(S).
3939

4040
req_tcp_connect_timeout(Config) ->
@@ -69,7 +69,7 @@ dealer_tcp_connect_close(Config) ->
6969
TcpOpts = tcp_opts(Config),
7070
IP = proplists:get_value(localhost, Config, {127,0,0,1}),
7171
{ok, S} = ezmq_client_socket([{type, dealer}, {active, false}]),
72-
ok = ezmq:connect(S, tcp, IP, 5555, [TcpOpts]),
72+
ok = ezmq:connect(S, tcp, IP, 5555, TcpOpts),
7373
ezmq:close(S).
7474

7575
dealer_tcp_connect_timeout(Config) ->
@@ -363,7 +363,7 @@ create_bound_pair(Config, Type1, Type2, Mode) ->
363363
ok = ezmq:bind(S1, tcp, 0, [{reuseaddr, true}|TcpOpts]),
364364
{ok, [{_, IP, Port}|_]} = ezmq:sockname(S1),
365365
ct:pal("IP: ~p, Port: ~p~n", [IP, Port]),
366-
ok = ezmq:connect(S2, tcp, IP, Port, [TcpOpts]),
366+
ok = ezmq:connect(S2, tcp, IP, Port, TcpOpts),
367367
{S1, S2}.
368368

369369
%% assert that message queue is empty....

test/ezmq_event_SUITE.erl

+7-7
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ ezmq_server_events_t(Contig) ->
3434
Port = 5555,
3535
ClientIdentity = <<"client">>,
3636
ServerIdentity = <<"server">>,
37-
{ok, ServerSocket} = ezmq:socket([{type, router}, {active, true}, {reuseaddr, true}, {identity, ServerIdentity}, {need_events, true}]),
38-
?assertEqual(ok, ezmq:bind(ServerSocket, tcp, Port, [{ip, IP}])),
37+
{ok, ServerSocket} = ezmq:socket([{type, router}, {active, true}, {identity, ServerIdentity}, {need_events, true}]),
38+
?assertEqual(ok, ezmq:bind(ServerSocket, tcp, Port, [{ip, IP}, {reuseaddr, true}])),
3939
receive
4040
{zmq_event, ServerSocket, Event} ->
4141
?debugFmt("ERROR: No connections. Unhandled events: ~p~n", [Event]),
@@ -92,8 +92,8 @@ ezmq_client_events_t(Contig) ->
9292
Port = 5555,
9393
ClientIdentity = <<"client">>,
9494
ServerIdentity = <<"server">>,
95-
{ok, ServerSocket} = ezmq:socket([{type, router}, {active, true}, {reuseaddr, true}, {identity, ServerIdentity}]),
96-
?assertEqual(ok, ezmq:bind(ServerSocket, tcp, Port, [{ip, IP}])),
95+
{ok, ServerSocket} = ezmq:socket([{type, router}, {active, true}, {identity, ServerIdentity}]),
96+
?assertEqual(ok, ezmq:bind(ServerSocket, tcp, Port, [{ip, IP}, {reuseaddr, true}])),
9797
receive
9898
{zmq_event, ServerSocket, Event} ->
9999
?debugFmt("ERROR: No connections. Unhandled events: ~p~n", [Event]),
@@ -150,8 +150,8 @@ no_events_t(Contig) ->
150150
Port = 5555,
151151
ClientIdentity = <<"client">>,
152152
ServerIdentity = <<"server">>,
153-
{ok, ServerSocket} = ezmq:socket([{type, router}, {active, true}, {identity, ServerIdentity}, {reuseaddr, true}]),
154-
?assertEqual(ok, ezmq:bind(ServerSocket, tcp, Port, [{ip, IP}])),
153+
{ok, ServerSocket} = ezmq:socket([{type, router}, {active, true}, {identity, ServerIdentity}]),
154+
?assertEqual(ok, ezmq:bind(ServerSocket, tcp, Port, [{ip, IP}, {reuseaddr, true}])),
155155
%% Start client
156156
{ok, ClientSocket} = ezmq:start([{type, dealer}, {identity, ClientIdentity}]),
157157
ezmq:connect(ClientSocket, tcp, IP, Port, []),
@@ -178,4 +178,4 @@ clear_mailbox() ->
178178
after 0 ->
179179
ok
180180
end.
181-
%%++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
181+
%%++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

0 commit comments

Comments
 (0)