mirror of
https://github.com/dotnet/MQTTnet.git
synced 2026-10-15 00:15:15 +08:00
Reject duplicate MQTT 5 PUBLISH singleton properties (#2261)
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using MQTTnet.Exceptions;
|
||||
using MQTTnet.Formatter;
|
||||
using MQTTnet.Packets;
|
||||
|
||||
namespace MQTTnet.Tests.Formatter;
|
||||
|
||||
[TestClass]
|
||||
public sealed class MqttV5PublishPropertyValidation_Tests
|
||||
{
|
||||
[TestMethod]
|
||||
[DataRow("0100")]
|
||||
[DataRow("0200000000")]
|
||||
[DataRow("030000")]
|
||||
[DataRow("08000161")]
|
||||
[DataRow("090000")]
|
||||
[DataRow("230001")]
|
||||
public void Publish_Rejects_Duplicate_Singleton_Property(string propertyHex)
|
||||
{
|
||||
var property = Convert.FromHexString(propertyHex);
|
||||
byte[] packet = [0x30, (byte)(4 + 2 * property.Length), 0, 1, (byte)'a', (byte)(2 * property.Length), .. property, .. property];
|
||||
|
||||
Assert.ThrowsExactly<MqttProtocolViolationException>(() => MqttPacketSerializationHelper.DecodePacket(packet, MqttProtocolVersion.V500));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Publish_Allows_Repeated_Subscription_Identifiers_And_User_Properties()
|
||||
{
|
||||
byte[] packet = [0x30, 18, 0, 1, (byte)'a', 14, 0x0B, 1, 0x26, 0, 0, 0, 0, 0x0B, 1, 0x26, 0, 0, 0, 0];
|
||||
var decoded = (MqttPublishPacket)MqttPacketSerializationHelper.DecodePacket(packet, MqttProtocolVersion.V500);
|
||||
|
||||
CollectionAssert.AreEqual(new uint[] { 1, 1 }, decoded.SubscriptionIdentifiers);
|
||||
Assert.HasCount(2, decoded.UserProperties);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -476,8 +476,28 @@ public sealed class MqttV5PacketDecoder
|
||||
}
|
||||
|
||||
var propertiesReader = new MqttV5PropertiesReader(_bufferReader);
|
||||
var seenSingletonProperties = 0;
|
||||
while (propertiesReader.MoveNext())
|
||||
{
|
||||
// MQTT 5.0 section 3.3.2.3 permits only User Properties and
|
||||
// Subscription Identifiers to occur more than once in PUBLISH.
|
||||
var propertyFlag = propertiesReader.CurrentPropertyId switch
|
||||
{
|
||||
MqttPropertyId.PayloadFormatIndicator => 1,
|
||||
MqttPropertyId.MessageExpiryInterval => 2,
|
||||
MqttPropertyId.ContentType => 4,
|
||||
MqttPropertyId.ResponseTopic => 8,
|
||||
MqttPropertyId.CorrelationData => 16,
|
||||
MqttPropertyId.TopicAlias => 32,
|
||||
_ => 0
|
||||
};
|
||||
|
||||
if ((seenSingletonProperties & propertyFlag) != 0)
|
||||
{
|
||||
throw new MqttProtocolViolationException($"Property '{propertiesReader.CurrentPropertyId}' must not occur more than once in a PUBLISH packet.");
|
||||
}
|
||||
|
||||
seenSingletonProperties |= propertyFlag;
|
||||
if (propertiesReader.CurrentPropertyId == MqttPropertyId.PayloadFormatIndicator)
|
||||
{
|
||||
packet.PayloadFormatIndicator = propertiesReader.ReadPayloadFormatIndicator();
|
||||
|
||||
Reference in New Issue
Block a user