Skip to content

Commit 814d44d

Browse files
committed
Convert array from AMQP 1.0 to AMQP 0.9.1
Fix the following crash when an AMQP 0.9.1 client consumes an AMQP 1.0 encoded message that contains an array value in message annotations: ``` crasher: initial call: rabbit_channel:init/1 pid: <0.685.0> registered_name: [] exception exit: {function_clause, [{mc_amqpl,to_091, [<<"x-array">>, {array,utf8,[{utf8,<<"e1">>},{utf8,<<"e2">>}]}], [{file,"mc_amqpl.erl"},{line,737}]}, {mc_amqpl,'-convert_from/3-fun-3-',1, [{file,"mc_amqpl.erl"},{line,168}]}, {lists,filtermap_1,2, [{file,"lists.erl"},{line,2279}]}, {mc_amqpl,convert_from,3, [{file,"mc_amqpl.erl"},{line,158}]}, {mc,convert,3,[{file,"mc.erl"},{line,332}]}, {rabbit_channel,handle_deliver0,4, [{file,"rabbit_channel.erl"},{line,2619}]}, {lists,foldl_1,3,[{file,"lists.erl"},{line,2151}]}, {lists,foldl,3,[{file,"lists.erl"},{line,2146}]}]} ```
1 parent d7c4e94 commit 814d44d

File tree

4 files changed

+29
-6
lines changed

4 files changed

+29
-6
lines changed

deps/amqp10_client/src/amqp10_msg.erl

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -402,8 +402,8 @@ set_delivery_annotations(
402402
Anns1 = #'v1_0.delivery_annotations'{content = maps:to_list(Anns)},
403403
Msg#amqp10_msg{delivery_annotations = Anns1}.
404404

405-
-spec set_message_annotations(#{binary() => binary() | integer() | string()},
406-
amqp10_msg()) -> amqp10_msg().
405+
-spec set_message_annotations(#{binary() => binary() | number() | string() | tuple()},
406+
amqp10_msg()) -> amqp10_msg().
407407
set_message_annotations(Props,
408408
#amqp10_msg{message_annotations = undefined} =
409409
Msg) ->
@@ -436,7 +436,9 @@ wrap_ap_value(V) when is_integer(V) ->
436436
end;
437437
wrap_ap_value(V) when is_number(V) ->
438438
%% AMQP double and Erlang float are both 64-bit.
439-
{double, V}.
439+
{double, V};
440+
wrap_ap_value(TaggedValue) when is_tuple(TaggedValue) ->
441+
TaggedValue.
440442

441443
%% LOCAL
442444
header_value(durable, undefined) -> false;

deps/rabbit/src/mc_amqpl.erl

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -754,9 +754,14 @@ to_091(Key, false) -> {Key, bool, false};
754754
to_091(Key, undefined) -> {Key, void, undefined};
755755
to_091(Key, null) -> {Key, void, undefined};
756756
to_091(Key, {list, L}) ->
757-
{Key, array, [to_091(V) || V <- L]};
757+
to_091_array(Key, L);
758758
to_091(Key, {map, M}) ->
759-
{Key, table, [to_091(unwrap(K), V) || {K, V} <- M]}.
759+
{Key, table, [to_091(unwrap(K), V) || {K, V} <- M]};
760+
to_091(Key, {array, _T, L}) ->
761+
to_091_array(Key, L).
762+
763+
to_091_array(Key, L) ->
764+
{Key, array, [to_091(V) || V <- L]}.
760765

761766
to_091({utf8, V}) -> {longstr, V};
762767
to_091({symbol, V}) -> {longstr, V};

deps/rabbit/test/amqp_client_SUITE.erl

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1339,6 +1339,13 @@ amqp_amqpl(QType, Config) ->
13391339
message_format = {uint, 0}},
13401340
Body1,
13411341
Footer])),
1342+
%% Send with an array value in message annotations.
1343+
ok = amqp10_client:send_msg(
1344+
Sender,
1345+
amqp10_msg:set_message_annotations(
1346+
#{<<"x-array">> => {array, utf8, [{utf8, <<"e1">>},
1347+
{utf8, <<"e2">>}]}},
1348+
amqp10_msg:new(<<>>, Body1, true))),
13421349

13431350
ok = amqp10_client:detach_link(Sender),
13441351
flush(detached),
@@ -1418,6 +1425,13 @@ amqp_amqpl(QType, Config) ->
14181425
?assertEqual([Body1, Footer], amqp10_framing:decode_bin(Payload10))
14191426
after 5000 -> ct:fail({missing_deliver, ?LINE})
14201427
end,
1428+
receive {_, #amqp_msg{payload = Payload11,
1429+
props = #'P_basic'{headers = Headers11}}} ->
1430+
?assertEqual([Body1], amqp10_framing:decode_bin(Payload11)),
1431+
?assertEqual({array, [{longstr, <<"e1">>}, {longstr, <<"e2">>}]},
1432+
rabbit_misc:table_lookup(Headers11, <<"x-array">>))
1433+
after 5000 -> ct:fail({missing_deliver, ?LINE})
1434+
end,
14211435

14221436
ok = rabbit_ct_client_helpers:close_channel(Ch),
14231437
{ok, _} = rabbitmq_amqp_client:delete_queue(LinkPair, QName),

deps/rabbit/test/mc_unit_SUITE.erl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -532,7 +532,8 @@ amqp_amqpl(_Config) ->
532532
MAC = [
533533
{{symbol, <<"x-stream-filter">>}, {utf8, <<"apple">>}},
534534
thead2('x-list', list, [utf8(<<"l">>)]),
535-
thead2('x-map', map, [{utf8(<<"k">>), utf8(<<"v">>)}])
535+
thead2('x-map', map, [{utf8(<<"k">>), utf8(<<"v">>)}]),
536+
{{symbol, <<"x-array">>}, {array, utf8, [{utf8, <<"a">>}]}}
536537
],
537538
M = #'v1_0.message_annotations'{content = MAC},
538539
P = #'v1_0.properties'{content_type = {symbol, <<"ctype">>},
@@ -598,6 +599,7 @@ amqp_amqpl(_Config) ->
598599
?assertMatch({_, longstr, <<"apple">>}, header(<<"x-stream-filter">>, HL)),
599600
?assertMatch({_ ,array, [{longstr,<<"l">>}]}, header(<<"x-list">>, HL)),
600601
?assertMatch({_, table, [{<<"k">>,longstr,<<"v">>}]}, header(<<"x-map">>, HL)),
602+
?assertMatch({_, array, [{longstr, <<"a">>}]}, header(<<"x-array">>, HL)),
601603

602604
?assertMatch({_, long, 5}, header(<<"long">>, HL)),
603605
?assertMatch({_, long, 5}, header(<<"ulong">>, HL)),

0 commit comments

Comments
 (0)