diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/rabbit_exchange.erl | 28 | ||||
| -rw-r--r-- | src/rabbit_exchange_type_registry.erl | 15 |
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. %%--------------------------------------------------------------------------- |
