From 09e33934867936399b5f6d81920b871da192b859 Mon Sep 17 00:00:00 2001 From: firest Date: Wed, 13 Apr 2022 10:28:21 +0800 Subject: [PATCH] fix(frame): prohibit empty topic in strict mode --- src/emqx_frame.erl | 11 +++++++++++ test/emqx_frame_SUITE.erl | 17 +++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/src/emqx_frame.erl b/src/emqx_frame.erl index 2149833d6..8dd657253 100644 --- a/src/emqx_frame.erl +++ b/src/emqx_frame.erl @@ -252,6 +252,7 @@ parse_packet(#mqtt_packet_header{type = ?PUBLISH, qos = QoS}, Bin, (PacketId =/= undefined) andalso StrictMode andalso validate_packet_id(PacketId), {Properties, Payload} = parse_properties(Rest1, Ver, StrictMode), + ok = ensure_topic_name_valid(StrictMode, TopicName, Properties), Publish = #mqtt_packet_publish{topic_name = TopicName, packet_id = PacketId, properties = Properties @@ -338,6 +339,7 @@ parse_will_message(Packet = #mqtt_packet_connect{will_flag = true, {Props, Rest} = parse_properties(Bin, Ver, StrictMode), {Topic, Rest1} = parse_utf8_string(Rest, StrictMode), {Payload, Rest2} = parse_binary_data(Rest1), + ok = ensure_topic_name_valid(StrictMode, Topic, Props), {Packet#mqtt_packet_connect{will_props = Props, will_topic = Topic, will_payload = Payload @@ -503,6 +505,15 @@ parse_binary_data(Bin) when 2 > byte_size(Bin) -> error(malformed_binary_data_length). +ensure_topic_name_valid(false, _TopicName, _Properties) -> + ok; +ensure_topic_name_valid(true, TopicName, _Properties) when TopicName =/= <<>> -> + ok; +ensure_topic_name_valid(true, <<>>, #{'Topic-Alias' := _}) -> + ok; +ensure_topic_name_valid(true, <<>>, _) -> + error(empty_topic_name). + %%-------------------------------------------------------------------- %% Serialize MQTT Packet %%-------------------------------------------------------------------- diff --git a/test/emqx_frame_SUITE.erl b/test/emqx_frame_SUITE.erl index c51ab8d7f..eca130bbe 100644 --- a/test/emqx_frame_SUITE.erl +++ b/test/emqx_frame_SUITE.erl @@ -46,6 +46,8 @@ groups() -> t_parse_frame_malformed_variable_byte_integer, t_parse_frame_variable_byte_integer, t_parse_malformed_utf8_string, + t_parse_empty_topic_name, + t_parse_empty_topic_name_with_alias, t_parse_frame_proxy_protocol %% proxy_protocol_config_disabled packet. ]}, {connect, [parallel], @@ -161,6 +163,21 @@ t_parse_malformed_utf8_string(_) -> ParseState = emqx_frame:initial_parse_state(#{strict_mode => true}), ?catch_error(utf8_string_invalid, emqx_frame:parse(MalformedPacket, ParseState)). +t_parse_empty_topic_name(_) -> + Packet = ?PUBLISH_PACKET(?QOS_1, <<>>, 1, #{}, <<>>), + ?assertEqual(Packet, parse_serialize(Packet, #{strict_mode => false})), + ?catch_error(empty_topic_name, parse_serialize(Packet, #{strict_mode => true})). + +t_parse_empty_topic_name_with_alias(_) -> + Props = #{'Topic-Alias' => 16#AB}, + Packet = ?PUBLISH_PACKET(?QOS_1, <<>>, 1, Props, <<>>), + ?assertEqual( + Packet, parse_serialize(Packet, #{strict_mode => false, version => ?MQTT_PROTO_V5}) + ), + ?assertEqual( + Packet, parse_serialize(Packet, #{strict_mode => true, version => ?MQTT_PROTO_V5}) + ). + t_parse_frame_proxy_protocol(_) -> BinList = [ <<"PROXY TCP4 ">>, <<"PROXY TCP6 ">>, <<"PROXY UNKNOWN">> , <<"\r\n\r\n\0\r\nQUIT\n">>],