Merge pull request #7558 from lafirest/fix/empty_topic_with_alias

fix(frame): fix empty topic check error
This commit is contained in:
Xinyu Liu 2022-04-08 18:07:42 +08:00 committed by GitHub
commit 0a77e1a9b1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 20 additions and 14 deletions

View File

@ -265,7 +265,7 @@ parse_packet(#mqtt_packet_header{type = ?CONNACK}, <<AckFlags:8, ReasonCode:8, R
parse_packet(#mqtt_packet_header{type = ?PUBLISH, qos = QoS}, Bin,
#{strict_mode := StrictMode, version := Ver}) ->
{TopicName, Rest} = parse_topic_name(Bin, StrictMode),
{TopicName, Rest} = parse_utf8_string(Bin, StrictMode),
{PacketId, Rest1} = case QoS of
?QOS_0 -> {undefined, Rest};
_ -> parse_packet_id(Rest)
@ -273,6 +273,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
@ -357,8 +358,9 @@ parse_will_message(Packet = #mqtt_packet_connect{will_flag = true,
proto_ver = Ver},
Bin, StrictMode) ->
{Props, Rest} = parse_properties(Bin, Ver, StrictMode),
{Topic, Rest1} = parse_topic_name(Rest, 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
@ -524,13 +526,14 @@ parse_binary_data(Bin)
when 2 > byte_size(Bin) ->
error(malformed_binary_data_length).
parse_topic_name(Bin, false) ->
parse_utf8_string(Bin, false);
parse_topic_name(Bin, true) ->
case parse_utf8_string(Bin, true) of
{<<>>, _Rest} -> error(empty_topic_name);
Result -> Result
end.
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

View File

@ -163,12 +163,15 @@ t_parse_malformed_utf8_string(_) ->
?catch_error(utf8_string_invalid, emqx_frame:parse(MalformedPacket, ParseState)).
t_parse_empty_topic_name(_) ->
Packet = <<48, 4, 0, 0, 0, 1>>,
NormalState = emqx_frame:initial_parse_state(#{strict_mode => false}),
?assertMatch({_, _}, emqx_frame:parse(Packet, NormalState)),
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})).
StrictState = emqx_frame:initial_parse_state(#{strict_mode => true}),
?catch_error(empty_topic_name, emqx_frame:parse(Packet, StrictState)).
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})),
?assertEqual(Packet, parse_serialize(Packet, #{strict_mode => true})).
t_parse_frame_proxy_protocol(_) ->
BinList = [ <<"PROXY TCP4 ">>, <<"PROXY TCP6 ">>, <<"PROXY UNKNOWN">>