summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/rabbit_exchange.erl28
-rw-r--r--src/rabbit_exchange_type_registry.erl15
2 files changed, 31 insertions, 12 deletions
diff --git a/src/rabbit_exchange.erl b/src/rabbit_exchange.erl
index 2c5ea99c90..f6cc030bd6 100644
--- a/src/rabbit_exchange.erl
+++ b/src/rabbit_exchange.erl
@@ -162,6 +162,7 @@ declare(ExchangeName, Type, Durable, AutoDelete, Args) ->
Err -> Err
end.
+%% Used with atoms from records; e.g., the type is expected to exist.
type_to_module(T) ->
case rabbit_exchange_type_registry:lookup_module(T) of
{ok, Module} -> Module;
@@ -170,18 +171,25 @@ type_to_module(T) ->
"invalid exchange type '~s'", [T])
end.
+%% Used with binaries sent over the wire; the type may not exist.
check_type(TypeBin) ->
- T = rabbit_exchange_type_registry:binary_to_type(TypeBin),
- Module = type_to_module(T),
- case catch Module:description() of
- {'EXIT', {undef, [{_, description, []} | _]}} ->
+ case rabbit_exchange_type_registry:binary_to_type(TypeBin) of
+ {error, not_found} ->
rabbit_misc:protocol_error(
- command_invalid, "invalid exchange type '~s'", [T]);
- {'EXIT', _} ->
- rabbit_misc:protocol_error(
- command_invalid, "problem loading exchange type '~s'", [T]);
- _ ->
- T
+ command_invalid, "unknown exchange type '~s'", [TypeBin]);
+ T ->
+ Module = type_to_module(T),
+ %% sanity check
+ case catch Module:description() of
+ {'EXIT', {undef, [{_, description, []} | _]}} ->
+ rabbit_misc:protocol_error(
+ command_invalid, "invalid exchange type '~s'", [T]);
+ {'EXIT', _} ->
+ rabbit_misc:protocol_error(
+ command_invalid, "problem loading exchange type '~s'", [T]);
+ _ ->
+ T
+ end
end.
assert_type(#exchange{ type = ActualType }, RequiredType)
diff --git a/src/rabbit_exchange_type_registry.erl b/src/rabbit_exchange_type_registry.erl
index 722a926e9f..56ce9dc9be 100644
--- a/src/rabbit_exchange_type_registry.erl
+++ b/src/rabbit_exchange_type_registry.erl
@@ -55,8 +55,15 @@ start_link() ->
register(TypeName, ModuleName) ->
gen_server:call(?SERVER, {register, TypeName, ModuleName}).
+%% This is used with user-supplied arguments (e.g., on exchange
+%% declare), so we restrict it to existing atoms only. This means it
+%% can throw a badarg, indicating that the type cannot have been
+%% registered.
binary_to_type(TypeBin) when is_binary(TypeBin) ->
- list_to_atom(binary_to_list(TypeBin)).
+ case catch list_to_existing_atom(binary_to_list(TypeBin)) of
+ {'EXIT', {badarg, _}} -> {error, not_found};
+ TypeAtom -> TypeAtom
+ end.
lookup_module(T) when is_atom(T) ->
case ets:lookup(?ETS_NAME, T) of
@@ -68,9 +75,13 @@ lookup_module(T) when is_atom(T) ->
%%---------------------------------------------------------------------------
+internal_binary_to_type(TypeBin) when is_binary(TypeBin) ->
+ list_to_atom(binary_to_list(TypeBin)).
+
internal_register(TypeName, ModuleName)
when is_binary(TypeName), is_atom(ModuleName) ->
- true = ets:insert(?ETS_NAME, {binary_to_type(TypeName), ModuleName}),
+ true = ets:insert(?ETS_NAME,
+ {internal_binary_to_type(TypeName), ModuleName}),
ok.
%%---------------------------------------------------------------------------