File 5311-Guard-gen_-arguments-in-the-API.patch of Package erlang
From b56ad774315b78787c0107d6a90281ec929a312a Mon Sep 17 00:00:00 2001
From: Raimo Niskanen <raimo@erlang.org>
Date: Fri, 10 Nov 2023 18:29:20 +0100
Subject: [PATCH] Guard `gen_*` arguments in the API
There is also a possibility to `throw/1` from `gen:where/1`, catch
that in the `gen_*` API functions, and convert to a 'badarg' there,
but in that case we also need to fix gen_fsm to not leak a `throw/1`,
so we leave it at this. A bad name gives a 'badarg' from
`gen:where/1`, which is not to deep below the API function.
---
lib/stdlib/src/gen.erl | 4 +++-
lib/stdlib/src/gen_event.erl | 26 +++++++++++++++++++-------
lib/stdlib/src/gen_server.erl | 30 ++++++++++++++++++++++++------
lib/stdlib/src/gen_statem.erl | 32 +++++++++++++++++++++++++-------
lib/wx/src/wx_object.erl | 20 ++++++++++++++++----
5 files changed, 87 insertions(+), 25 deletions(-)
diff --git a/lib/stdlib/src/gen.erl b/lib/stdlib/src/gen.erl
index d03ca78e7c..15c322cf68 100644
--- a/lib/stdlib/src/gen.erl
+++ b/lib/stdlib/src/gen.erl
@@ -614,7 +614,9 @@ do_for_proc({_Name, Node} = Process, Fun) when is_atom(Node) ->
%%%-----------------------------------------------------------------
where({global, Name}) -> global:whereis_name(Name);
where({via, Module, Name}) -> Module:whereis_name(Name);
-where({local, Name}) -> whereis(Name).
+where({local, Name}) -> whereis(Name);
+where(ServerName) ->
+ error(badarg, [ServerName]).
register_name({local, Name} = LN) ->
try register(Name, self()) of
diff --git a/lib/stdlib/src/gen_event.erl b/lib/stdlib/src/gen_event.erl
index fd4b5d9add..5efb931df9 100644
--- a/lib/stdlib/src/gen_event.erl
+++ b/lib/stdlib/src/gen_event.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2022. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2023. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -191,11 +191,15 @@ start() ->
start(Name) when is_tuple(Name) ->
gen:start(?MODULE, nolink, Name, ?NO_CALLBACK, [], []);
start(Options) when is_list(Options) ->
- gen:start(?MODULE, nolink, ?NO_CALLBACK, [], Options).
+ gen:start(?MODULE, nolink, ?NO_CALLBACK, [], Options);
+start(Arg) ->
+ error(badarg, [Arg]).
-spec start(emgr_name(), [option()]) -> start_ret().
+start(Name, Options) when is_tuple(Name), is_list(Options) ->
+ gen:start(?MODULE, nolink, Name, ?NO_CALLBACK, [], Options);
start(Name, Options) ->
- gen:start(?MODULE, nolink, Name, ?NO_CALLBACK, [], Options).
+ error(badarg, [Name, Options]).
-spec start_link() -> start_ret().
start_link() ->
@@ -205,11 +209,15 @@ start_link() ->
start_link(Name) when is_tuple(Name) ->
gen:start(?MODULE, link, Name, ?NO_CALLBACK, [], []);
start_link(Options) when is_list(Options) ->
- gen:start(?MODULE, link, ?NO_CALLBACK, [], Options).
+ gen:start(?MODULE, link, ?NO_CALLBACK, [], Options);
+start_link(Arg) ->
+ error(badarg, [Arg]).
-spec start_link(emgr_name(), [option()]) -> start_ret().
+start_link(Name, Options) when is_tuple(Name), is_list(Options) ->
+ gen:start(?MODULE, link, Name, ?NO_CALLBACK, [], Options);
start_link(Name, Options) ->
- gen:start(?MODULE, link, Name, ?NO_CALLBACK, [], Options).
+ error(badarg, [Name, Options]).
-spec start_monitor() -> start_mon_ret().
start_monitor() ->
@@ -219,11 +227,15 @@ start_monitor() ->
start_monitor(Name) when is_tuple(Name) ->
gen:start(?MODULE, monitor, Name, ?NO_CALLBACK, [], []);
start_monitor(Options) when is_list(Options) ->
- gen:start(?MODULE, monitor, ?NO_CALLBACK, [], Options).
+ gen:start(?MODULE, monitor, ?NO_CALLBACK, [], Options);
+start_monitor(Arg) ->
+ error(badarg, [Arg]).
-spec start_monitor(emgr_name(), [option()]) -> start_mon_ret().
+start_monitor(Name, Options) when is_tuple(Name), is_list(Options) ->
+ gen:start(?MODULE, monitor, Name, ?NO_CALLBACK, [], Options);
start_monitor(Name, Options) ->
- gen:start(?MODULE, monitor, Name, ?NO_CALLBACK, [], Options).
+ error(badarg, [Name, Options]).
%% -spec init_it(pid(), 'self' | pid(), emgr_name(), module(), [term()], [_]) ->
init_it(Starter, self, Name, Mod, Args, Options) ->
diff --git a/lib/stdlib/src/gen_server.erl b/lib/stdlib/src/gen_server.erl
index c574f2aeb2..1ffbdfefef 100644
--- a/lib/stdlib/src/gen_server.erl
+++ b/lib/stdlib/src/gen_server.erl
@@ -285,8 +285,11 @@
) ->
start_ret().
%%
+start(Module, Args, Options)
+ when is_atom(Module), is_list(Options) ->
+ gen:start(?MODULE, nolink, Module, Args, Options);
start(Module, Args, Options) ->
- gen:start(?MODULE, nolink, Module, Args, Options).
+ error(badarg, [Module, Args, Options]).
-spec start(
ServerName :: server_name(),
@@ -296,8 +299,11 @@ start(Module, Args, Options) ->
) ->
start_ret().
%%
+start(ServerName, Module, Args, Options)
+ when is_tuple(ServerName), is_atom(Module), is_list(Options) ->
+ gen:start(?MODULE, nolink, ServerName, Module, Args, Options);
start(ServerName, Module, Args, Options) ->
- gen:start(?MODULE, nolink, ServerName, Module, Args, Options).
+ error(badarg, [ServerName, Module, Args, Options]).
-spec start_link(
Module :: module(),
@@ -306,8 +312,11 @@ start(ServerName, Module, Args, Options) ->
) ->
start_ret().
%%
+start_link(Module, Args, Options)
+ when is_atom(Module), is_list(Options) ->
+ gen:start(?MODULE, link, Module, Args, Options);
start_link(Module, Args, Options) ->
- gen:start(?MODULE, link, Module, Args, Options).
+ error(badarg, [Module, Args, Options]).
-spec start_link(
ServerName :: server_name(),
@@ -317,8 +326,11 @@ start_link(Module, Args, Options) ->
) ->
start_ret().
%%
+start_link(ServerName, Module, Args, Options)
+ when is_tuple(ServerName), is_atom(Module), is_list(Options) ->
+ gen:start(?MODULE, link, ServerName, Module, Args, Options);
start_link(ServerName, Module, Args, Options) ->
- gen:start(?MODULE, link, ServerName, Module, Args, Options).
+ error(badarg, [ServerName, Module, Args, Options]).
-spec start_monitor(
Module :: module(),
@@ -327,8 +339,11 @@ start_link(ServerName, Module, Args, Options) ->
) ->
start_mon_ret().
%%
+start_monitor(Module, Args, Options)
+ when is_atom(Module), is_list(Options) ->
+ gen:start(?MODULE, monitor, Module, Args, Options);
start_monitor(Module, Args, Options) ->
- gen:start(?MODULE, monitor, Module, Args, Options).
+ error(badarg, [Module, Args, Options]).
-spec start_monitor(
ServerName :: server_name(),
@@ -338,8 +353,11 @@ start_monitor(Module, Args, Options) ->
) ->
start_mon_ret().
%%
+start_monitor(ServerName, Module, Args, Options)
+ when is_tuple(ServerName), is_atom(Module), is_list(Options) ->
+ gen:start(?MODULE, monitor, ServerName, Module, Args, Options);
start_monitor(ServerName, Module, Args, Options) ->
- gen:start(?MODULE, monitor, ServerName, Module, Args, Options).
+ error(badarg, [ServerName, Module, Args, Options]).
%% -----------------------------------------------------------------
diff --git a/lib/stdlib/src/gen_statem.erl b/lib/stdlib/src/gen_statem.erl
index 849bf45561..ee85646e30 100644
--- a/lib/stdlib/src/gen_statem.erl
+++ b/lib/stdlib/src/gen_statem.erl
@@ -559,43 +559,61 @@ event_type(Type) ->
-spec start(
Module :: module(), Args :: term(), Opts :: [start_opt()]) ->
start_ret().
+start(Module, Args, Opts)
+ when is_atom(Module), is_list(Opts) ->
+ gen:start(?MODULE, nolink, Module, Args, Opts);
start(Module, Args, Opts) ->
- gen:start(?MODULE, nolink, Module, Args, Opts).
+ error(badarg, [Module, Args, Opts]).
%%
-spec start(
ServerName :: server_name(),
Module :: module(), Args :: term(), Opts :: [start_opt()]) ->
start_ret().
+start(ServerName, Module, Args, Opts)
+ when is_tuple(ServerName), is_atom(Module), is_list(Opts) ->
+ gen:start(?MODULE, nolink, ServerName, Module, Args, Opts);
start(ServerName, Module, Args, Opts) ->
- gen:start(?MODULE, nolink, ServerName, Module, Args, Opts).
+ error(badarg, [ServerName, Module, Args, Opts]).
%% Start and link to a state machine
-spec start_link(
Module :: module(), Args :: term(), Opts :: [start_opt()]) ->
start_ret().
+start_link(Module, Args, Opts)
+ when is_atom(Module), is_list(Opts) ->
+ gen:start(?MODULE, link, Module, Args, Opts);
start_link(Module, Args, Opts) ->
- gen:start(?MODULE, link, Module, Args, Opts).
+ error(badarg, [Module, Args, Opts]).
%%
-spec start_link(
ServerName :: server_name(),
Module :: module(), Args :: term(), Opts :: [start_opt()]) ->
start_ret().
+start_link(ServerName, Module, Args, Opts)
+ when is_tuple(ServerName), is_atom(Module), is_list(Opts) ->
+ gen:start(?MODULE, link, ServerName, Module, Args, Opts);
start_link(ServerName, Module, Args, Opts) ->
- gen:start(?MODULE, link, ServerName, Module, Args, Opts).
+ error(badarg, [ServerName, Module, Args, Opts]).
%% Start and monitor a state machine
-spec start_monitor(
Module :: module(), Args :: term(), Opts :: [start_opt()]) ->
start_mon_ret().
+start_monitor(Module, Args, Opts)
+ when is_atom(Module), is_list(Opts) ->
+ gen:start(?MODULE, monitor, Module, Args, Opts);
start_monitor(Module, Args, Opts) ->
- gen:start(?MODULE, monitor, Module, Args, Opts).
+ error(badarg, [Module, Args, Opts]).
%%
-spec start_monitor(
ServerName :: server_name(),
Module :: module(), Args :: term(), Opts :: [start_opt()]) ->
start_mon_ret().
+start_monitor(ServerName, Module, Args, Opts)
+ when is_tuple(ServerName), is_atom(Module), is_list(Opts) ->
+ gen:start(?MODULE, monitor, ServerName, Module, Args, Opts);
start_monitor(ServerName, Module, Args, Opts) ->
- gen:start(?MODULE, monitor, ServerName, Module, Args, Opts).
+ error(badarg, [ServerName, Module, Args, Opts]).
%% Stop a state machine
-spec stop(ServerRef :: server_ref()) -> ok.
@@ -651,7 +669,7 @@ call(ServerRef, Request, {dirty_timeout, T} = Timeout) ->
call(ServerRef, Request, {clean_timeout, T} = Timeout) ->
call(ServerRef, Request, Timeout, T);
call(ServerRef, Request, {_, _} = Timeout) ->
- erlang:error(badarg, [ServerRef,Request,Timeout]);
+ error(badarg, [ServerRef,Request,Timeout]);
call(ServerRef, Request, Timeout) ->
call(ServerRef, Request, Timeout, Timeout).
diff --git a/lib/wx/src/wx_object.erl b/lib/wx/src/wx_object.erl
index 1a2d49faca..5e22c62eb3 100644
--- a/lib/wx/src/wx_object.erl
+++ b/lib/wx/src/wx_object.erl
@@ -199,8 +199,11 @@
Args::term(),
Flag::trace | log | {logfile, string()} | statistics | debug,
Options::[{timeout, timeout()} | {debug, [Flag]}].
+start(Mod, Args, Options)
+ when is_atom(Mod), is_list(Options) ->
+ gen_response(gen:start(?MODULE, nolink, Mod, Args, [get(?WXE_IDENTIFIER)|Options]));
start(Mod, Args, Options) ->
- gen_response(gen:start(?MODULE, nolink, Mod, Args, [get(?WXE_IDENTIFIER)|Options])).
+ error(badarg, [Mod, Args, Options]).
%% @doc Starts a generic wx_object server and invokes Mod:init(Args) in the
%% new process.
@@ -210,8 +213,11 @@ start(Mod, Args, Options) ->
Args::term(),
Flag::trace | log | {logfile, string()} | statistics | debug,
Options::[{timeout, timeout()} | {debug, [Flag]}].
+start(Name, Mod, Args, Options)
+ when is_tuple(Name), is_atom(Mod), is_list(Options) ->
+ gen_response(gen:start(?MODULE, nolink, Name, Mod, Args, [get(?WXE_IDENTIFIER)|Options]));
start(Name, Mod, Args, Options) ->
- gen_response(gen:start(?MODULE, nolink, Name, Mod, Args, [get(?WXE_IDENTIFIER)|Options])).
+ error(badarg, [Name, Mod, Args, Options]).
%% @doc Starts a generic wx_object server and invokes Mod:init(Args) in the
%% new process.
@@ -220,8 +226,11 @@ start(Name, Mod, Args, Options) ->
Args::term(),
Flag::trace | log | {logfile, string()} | statistics | debug,
Options::[{timeout, timeout()} | {debug, [Flag]}].
+start_link(Mod, Args, Options)
+ when is_atom(Mod), is_list(Options) ->
+ gen_response(gen:start(?MODULE, link, Mod, Args, [get(?WXE_IDENTIFIER)|Options]));
start_link(Mod, Args, Options) ->
- gen_response(gen:start(?MODULE, link, Mod, Args, [get(?WXE_IDENTIFIER)|Options])).
+ error(badarg, [Mod, Args, Options]).
%% @doc Starts a generic wx_object server and invokes Mod:init(Args) in the
%% new process.
@@ -231,8 +240,11 @@ start_link(Mod, Args, Options) ->
Args::term(),
Flag::trace | log | {logfile, string()} | statistics | debug,
Options::[{timeout, timeout()} | {debug, [Flag]}].
+start_link(Name, Mod, Args, Options)
+ when is_tuple(Name), is_atom(Mod), is_list(Options) ->
+ gen_response(gen:start(?MODULE, link, Name, Mod, Args, [get(?WXE_IDENTIFIER)|Options]));
start_link(Name, Mod, Args, Options) ->
- gen_response(gen:start(?MODULE, link, Name, Mod, Args, [get(?WXE_IDENTIFIER)|Options])).
+ error(badarg, [Name, Mod, Args, Options]).
gen_response({ok, Pid}) ->
receive {ack, Pid, Ref = #wx_ref{}} -> Ref end;
--
2.35.3