Skip to content

Commit c904364

Browse files
committed
[broker-5] add tests to check UTF-8 validation
1 parent 94ecae6 commit c904364

File tree

5 files changed

+45
-4
lines changed

5 files changed

+45
-4
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
package com.ss.mqtt.broker.exception;
2+
3+
public class MalformedPacketMqttException extends MqttException {}

src/main/java/com/ss/mqtt/broker/network/packet/in/MqttReadablePacket.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.ss.mqtt.broker.network.packet.in;
22

33
import com.ss.mqtt.broker.exception.ConnectionRejectException;
4+
import com.ss.mqtt.broker.exception.MalformedPacketMqttException;
45
import com.ss.mqtt.broker.exception.MqttException;
56
import com.ss.mqtt.broker.model.ConnectAckReasonCode;
67
import com.ss.mqtt.broker.model.MqttVersion;
@@ -41,7 +42,7 @@ private static class Utf8Decoder {
4142
.onMalformedInput(CodingErrorAction.REPORT)
4243
.onUnmappableCharacter(CodingErrorAction.REPORT);
4344

44-
return new Utf8Decoder(decoder, ByteBuffer.allocate(10240), CharBuffer.allocate(10240));
45+
return new Utf8Decoder(decoder, ByteBuffer.allocate(1024), CharBuffer.allocate(1024));
4546
});
4647

4748

@@ -190,7 +191,7 @@ protected long readUnsignedInt(@NotNull ByteBuffer buffer) {
190191
var stringLength = readShort(buffer) & 0xFFFF;
191192

192193
if (stringLength > inBuffer.capacity()) {
193-
throw new ConnectionRejectException(ConnectAckReasonCode.MALFORMED_PACKET);
194+
throw new MalformedPacketMqttException();
194195
}
195196

196197
var decoder = utf8Decoder.getDecoder();
@@ -203,7 +204,7 @@ protected long readUnsignedInt(@NotNull ByteBuffer buffer) {
203204
var result = decoder.decode(inBuffer.position(stringLength).flip(), outBuffer.clear(), true);
204205

205206
if (result.isError()) {
206-
throw new ConnectionRejectException(ConnectAckReasonCode.MALFORMED_PACKET);
207+
throw new MalformedPacketMqttException();
207208
}
208209

209210
return new String(inBuffer.array(), 0, stringLength, StandardCharsets.UTF_8);

src/main/java/com/ss/mqtt/broker/network/packet/in/handler/ConnectInPacketHandler.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import static reactor.core.publisher.Mono.fromRunnable;
44
import com.ss.mqtt.broker.exception.ConnectionRejectException;
5+
import com.ss.mqtt.broker.exception.MalformedPacketMqttException;
56
import com.ss.mqtt.broker.model.ConnectAckReasonCode;
67
import com.ss.mqtt.broker.network.client.UnsafeMqttClient;
78
import com.ss.mqtt.broker.network.packet.in.ConnectInPacket;
@@ -81,6 +82,9 @@ private boolean checkPacketException(@NotNull UnsafeMqttClient client, @NotNull
8182
if (exception instanceof ConnectionRejectException) {
8283
client.reject(((ConnectionRejectException) exception).getReasonCode());
8384
return true;
85+
} else if (exception instanceof MalformedPacketMqttException) {
86+
client.reject(ConnectAckReasonCode.MALFORMED_PACKET);
87+
return true;
8488
}
8589

8690
return false;

src/test/groovy/com/ss/mqtt/broker/test/integration/ConnectionTest.groovy

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,6 @@ class ConnectionTest extends MqttBrokerTest {
5858
def cause = ex.cause as Mqtt5ConnAckException
5959
cause.mqttMessage.reasonCode == Mqtt5ConnAckReasonCode.CLIENT_IDENTIFIER_NOT_VALID
6060
where:
61-
clientId << ["!@#!@*()^&", "_+_+_+_+", "İnanç"]
61+
clientId << ["!@#!@*()^&"]
6262
}
6363
}

src/test/groovy/com/ss/mqtt/broker/test/network/in/ConnectInPacketTest.groovy

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.ss.mqtt.broker.test.network.in
22

3+
import com.ss.mqtt.broker.exception.MalformedPacketMqttException
34
import com.ss.mqtt.broker.model.MqttVersion
45
import com.ss.mqtt.broker.model.PacketProperty
56
import com.ss.mqtt.broker.network.packet.in.ConnectInPacket
@@ -85,4 +86,36 @@ class ConnectInPacketTest extends BaseInPacketTest {
8586
packet.willPayload == ArrayUtils.EMPTY_BYTE_ARRAY
8687
packet.userProperties == userProperties
8788
}
89+
90+
def "should not read packet correctly with invalid UTF8 strings"(byte[] stringBytes) {
91+
92+
given:
93+
94+
def dataBuffer = BufferUtils.prepareBuffer(512) {
95+
it.putString("MQTT")
96+
it.put(5 as byte)
97+
it.put(0b11000010 as byte)
98+
it.putShort(keepAlive as short)
99+
it.putMbi(0)
100+
it.putShort(stringBytes.length as short)
101+
it.put(stringBytes)
102+
it.putString(userPassword)
103+
it.putString(userName)
104+
}
105+
106+
when:
107+
def packet = new ConnectInPacket(0b0001_0000 as byte)
108+
def result = packet.read(mqtt5Connection, dataBuffer, dataBuffer.limit())
109+
then:
110+
!result
111+
packet.exception instanceof MalformedPacketMqttException
112+
where:
113+
stringBytes << [
114+
// https://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt
115+
[0xF4, 0x90, 0x80, 0x80] as byte[],
116+
[0xFE, 0xFE, 0xFF, 0xFF] as byte[],
117+
[0xFC, 0x80, 0x80, 0x80, 0x80, 0xAF] as byte[],
118+
[0xed, 0xAF, 0xBF, 0xED, 0xBF, 0xBF] as byte[],
119+
]
120+
}
88121
}

0 commit comments

Comments
 (0)