Skip to content

Commit 1e761eb

Browse files
author
Bret Ambrose
committed
Merge branch 'JsMqtt-5-Validation' into JsMqtt-6-Protocol
2 parents 35c231c + 052a12d commit 1e761eb

21 files changed

Lines changed: 678 additions & 28 deletions

continuous-delivery/build-manylinux2014-aarch64.sh

Lines changed: 0 additions & 4 deletions
This file was deleted.

continuous-delivery/pack.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ mkdir $UNZIP
3939
tar -xf aws-crt-$CURRENT_TAG.tgz -C $UNZIP
4040
PACK_FILE_SIZE_KB=$(du -sk $UNZIP | awk '{print $1}')
4141
echo "Current package size: ${PACK_FILE_SIZE_KB}"
42-
if expr $PACK_FILE_SIZE_KB \> "$((35000))" ; then
42+
if expr $PACK_FILE_SIZE_KB \> "$((37000))" ; then
4343
# the package size is too large, return -1
4444
echo "Package size is too large!"
4545
exit -1

docsrc/typedoc-browser.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010
"../lib/browser/mqtt5.ts",
1111
"../lib/browser/ws.ts",
1212
"../lib/common/event.ts",
13-
"../lib/common/http.ts"
13+
"../lib/common/http.ts",
14+
"../lib/common/mqtt_shared.ts"
1415
],
1516
"tsconfig": "../tsconfig.browser.json",
1617
"out": "../docs/browser",

docsrc/typedoc-node.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414
"../lib/common/event.ts",
1515
"../lib/common/http.ts",
1616
"../lib/common/platform.ts",
17-
"../lib/common/resource_safety.ts"
17+
"../lib/common/resource_safety.ts",
18+
"../lib/common/mqtt_shared.ts"
1819
],
1920
"out": "../docs/node",
2021
"excludeExternals": true,

lib/browser/mqtt_internal/decoder.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,16 +47,12 @@ export function decodeLengthPrefixedString(payload: DataView, offset: number) :
4747
return [toUtf8(new Uint8Array(payload.buffer, index, stringLength)), index + stringLength];
4848
}
4949

50-
//Buffer.from(arrayBuffer, view.byteOffset, view.byteLength)
51-
5250
export function decodeBytes(payload: DataView, offset: number, length: number) : [ArrayBufferView, number] {
53-
// return [payload.buffer.slice(offset, offset + length), offset + length];
5451
return [Buffer.from(payload.buffer, offset, length), offset + length];
5552
}
5653

5754
export function decodeLengthPrefixedBytes(payload: DataView, offset: number) : [ArrayBufferView, number] {
5855
let [bytesLength, index] = decodeU16(payload, offset);
59-
// return [payload.buffer.slice(index, index + bytesLength), index + bytesLength];
6056
return [Buffer.from(payload.buffer, index, bytesLength), index + bytesLength];
6157
}
6258

@@ -77,6 +73,10 @@ export function decodeUserProperty(payload: DataView, offset: number, userProper
7773
// MQTT 311 Packet decoding functions
7874

7975
function decodeConnackPacket311(firstByte: number, payload: DataView) : model.ConnackPacketInternal {
76+
if (firstByte != model.PACKET_TYPE_FIRST_BYTE_CONNACK) {
77+
throw new CrtError("Connack with invalid first byte: " + firstByte);
78+
}
79+
8080
if (payload.byteLength != 2) {
8181
throw new CrtError("Connack packet invalid payload length");
8282
}
@@ -310,6 +310,10 @@ function decodeConnackPacket5(firstByte: number, payload: DataView) : model.Conn
310310
};
311311

312312
[flags, index] = decodeU8(payload, index);
313+
if ((flags & (~0x01)) != 0) {
314+
throw new CrtError("Connack invalid flags");
315+
}
316+
313317
connack.sessionPresent = (flags & model.CONNACK_FLAGS_SESSION_PRESENT) != 0;
314318
[connack.reasonCode, index] = decodeU8(payload, index);
315319

lib/browser/mqtt_internal/encoder.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -355,7 +355,7 @@ function getConnectPacketRemainingLengths5(packet: model.ConnectPacketBinary) :
355355
}
356356

357357
if (packet.will) {
358-
remaining_length += vli.getVliByteLength(will_properties_length) + will_properties_length
358+
remaining_length += vli.getVliByteLength(will_properties_length) + will_properties_length;
359359
remaining_length += 2 + packet.will.topicName.byteLength;
360360
remaining_length += 2; // payload length
361361
if (packet.will.payload) {

lib/browser/mqtt_internal/validate.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1241,8 +1241,8 @@ test('Binary connect packet validation - will too long', async () => {
12411241
// @ts-ignore
12421242
packet.will.payload = new Uint8Array(65537);
12431243

1244-
expect(() => { validate.validateBinaryOutboundPacket(packet, model.ProtocolMode.Mqtt311, settings); }).toThrow("exceeds established maximum packet size");
1245-
expect(() => { validate.validateBinaryOutboundPacket(packet, model.ProtocolMode.Mqtt5, settings); }).toThrow("exceeds established maximum packet size");
1244+
expect(() => { validate.validateBinaryOutboundPacket(packet, model.ProtocolMode.Mqtt311, settings); }).toThrow("will payload too long");
1245+
expect(() => { validate.validateBinaryOutboundPacket(packet, model.ProtocolMode.Mqtt5, settings); }).toThrow("will payload too long");
12461246
});
12471247

12481248
// Disconnect Validation

lib/browser/mqtt_internal/validate.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ function validateSubackReasonCode(value: mqtt5_packet.SubackReasonCode, mode: mo
243243
}
244244
}
245245

246-
function validatePubackReasonCode(value: mqtt5_packet.PubackReasonCode, mode: model.ProtocolMode) {
246+
function validatePubackReasonCode(value: mqtt5_packet.PubackReasonCode) {
247247
if (mqtt5_packet.PubackReasonCode[value] === undefined) {
248248
throw new CrtError(`"${value}" is not a valid MQTT5 PubackReasonCode`);
249249
}
@@ -510,7 +510,11 @@ function validateBinaryUserProperties(userProperties: Array<model.UserPropertyBi
510510

511511
function validateBinaryPublish(packet: model.PublishPacketBinary, mode: model.ProtocolMode, settings: mqtt5_common.NegotiatedSettings, isWill: boolean) {
512512
if (isWill) {
513-
validatePacketLength(packet, mode, 65535);
513+
// topic will be checked below
514+
515+
if (packet.payload && packet.payload.byteLength > 65535) {
516+
throw new CrtError("will payload too long");
517+
}
514518
} else {
515519
validatePacketLength(packet, mode, settings.maximumPacketSizeToServer);
516520
}
@@ -676,7 +680,7 @@ function validateInboundPublish(packet: model.PublishPacketInternal, mode: model
676680

677681
function validateInboundPuback(packet: model.PubackPacketInternal, mode: model.ProtocolMode) {
678682
validateRequiredPacketId(packet.packetId, "packetId");
679-
validatePubackReasonCode(packet.reasonCode, mode);
683+
validatePubackReasonCode(packet.reasonCode);
680684
}
681685

682686
function validateInboundConnack(packet: model.ConnackPacketInternal, mode: model.ProtocolMode) {

lib/browser/mqtt_internal/vli.spec.ts

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,35 @@ test('VLI encoding overflow', () => {
160160
expect(() => { vli.encodeVli(view1, 128 * 128 * 128 * 128) }).toThrow("Invalid VLI value");
161161
});
162162

163+
test('VLI decoding invalid offset', () => {
164+
let buffer1 = new Uint8Array([0, 128, 0]);
165+
expect(() => { vli.decodeVli(new DataView(buffer1.buffer, 1, 1), -1) }).toThrow("Invalid DataView offset");
166+
});
167+
168+
test('VLI decoding - insufficient data', () => {
169+
let buffer0 = new Uint8Array([0]);
170+
expect(vli.decodeVli(new DataView(buffer0.buffer, 0, 0), 0).type).toBe(vli.VliDecodeResultType.MoreData);
171+
172+
let buffer1 = new Uint8Array([0, 128, 0]);
173+
expect(vli.decodeVli(new DataView(buffer1.buffer, 1, 0), 0).type).toBe(vli.VliDecodeResultType.MoreData);
174+
expect(vli.decodeVli(new DataView(buffer1.buffer, 1, 1), 0).type).toBe(vli.VliDecodeResultType.MoreData);
175+
176+
let buffer2 = new Uint8Array([0, 0, 128, 128, 0]);
177+
expect(vli.decodeVli(new DataView(buffer2.buffer, 2, 0), 0).type).toBe(vli.VliDecodeResultType.MoreData);
178+
expect(vli.decodeVli(new DataView(buffer2.buffer, 2, 1), 0).type).toBe(vli.VliDecodeResultType.MoreData);
179+
expect(vli.decodeVli(new DataView(buffer2.buffer, 2, 2), 0).type).toBe(vli.VliDecodeResultType.MoreData);
180+
181+
let buffer3 = new Uint8Array([0, 0, 0, 128, 128, 128, 0]);
182+
expect(vli.decodeVli(new DataView(buffer3.buffer, 3, 0), 0).type).toBe(vli.VliDecodeResultType.MoreData);
183+
expect(vli.decodeVli(new DataView(buffer3.buffer, 3, 1), 0).type).toBe(vli.VliDecodeResultType.MoreData);
184+
expect(vli.decodeVli(new DataView(buffer3.buffer, 3, 2), 0).type).toBe(vli.VliDecodeResultType.MoreData);
185+
expect(vli.decodeVli(new DataView(buffer3.buffer, 3, 3), 0).type).toBe(vli.VliDecodeResultType.MoreData);
186+
187+
expect(vli.decodeVli(new DataView(buffer3.buffer, 1, 2), 2).type).toBe(vli.VliDecodeResultType.MoreData);
188+
expect(vli.decodeVli(new DataView(buffer3.buffer, 1, 3), 2).type).toBe(vli.VliDecodeResultType.MoreData);
189+
expect(vli.decodeVli(new DataView(buffer3.buffer, 1, 4), 2).type).toBe(vli.VliDecodeResultType.MoreData);
190+
expect(vli.decodeVli(new DataView(buffer3.buffer, 1, 5), 2).type).toBe(vli.VliDecodeResultType.MoreData);
191+
});
163192

164193
test('VLI decoding - 1 byte', () => {
165194
let buffer_0 = new Uint8Array([0]);
@@ -173,6 +202,11 @@ test('VLI decoding - 1 byte', () => {
173202

174203
let buffer_127 = new Uint8Array([127]);
175204
expect(vli.decodeVli(new DataView(buffer_127.buffer), 0).value).toBe(127);
205+
206+
let buffer_127_offset = new Uint8Array([0, 127, 0]);
207+
let result = vli.decodeVli(new DataView(buffer_127_offset.buffer), 1);
208+
expect(result.value).toBe(127);
209+
expect(result.nextOffset).toBe(2);
176210
});
177211

178212
test('VLI decoding - 2 byte', () => {
@@ -193,6 +227,11 @@ test('VLI decoding - 2 byte', () => {
193227

194228
let buffer_16382 = new Uint8Array([254, 127]);
195229
expect(vli.decodeVli(new DataView(buffer_16382.buffer), 0).value).toBe(16382);
230+
231+
let buffer_16382_offset = new Uint8Array([0, 0, 254, 127, 0]);
232+
let result = vli.decodeVli(new DataView(buffer_16382_offset.buffer), 2);
233+
expect(result.value).toBe(16382);
234+
expect(result.nextOffset).toBe(4);
196235
});
197236

198237
test('VLI decoding - 3 byte', () => {
@@ -210,6 +249,11 @@ test('VLI decoding - 3 byte', () => {
210249

211250
let buffer5 = new Uint8Array([255, 255, 127]);
212251
expect(vli.decodeVli(new DataView(buffer5.buffer), 0).value).toBe(128 * 128 * 128 - 1);
252+
253+
let buffer5_offset = new Uint8Array([0, 0, 0, 255, 255, 127, 0]);
254+
let result = vli.decodeVli(new DataView(buffer5_offset.buffer), 3);
255+
expect(result.value).toBe(128 * 128 * 128 - 1);
256+
expect(result.nextOffset).toBe(6);
213257
});
214258

215259
test('VLI decoding - 4 byte', () => {
@@ -219,8 +263,13 @@ test('VLI decoding - 4 byte', () => {
219263
let buffer2 = new Uint8Array([129, 128, 128, 1]);
220264
expect(vli.decodeVli(new DataView(buffer2.buffer), 0).value).toBe(128 * 128 * 128 + 1);
221265

222-
let buffer5 = new Uint8Array([255, 255, 255, 127]);
223-
expect(vli.decodeVli(new DataView(buffer5.buffer), 0).value).toBe(128 * 128 * 128 * 128 - 1);
266+
let buffer3 = new Uint8Array([255, 255, 255, 127]);
267+
expect(vli.decodeVli(new DataView(buffer3.buffer), 0).value).toBe(128 * 128 * 128 * 128 - 1);
268+
269+
let buffer3_offset = new Uint8Array([0, 0, 0, 0, 255, 255, 255, 127, 0]);
270+
let result = vli.decodeVli(new DataView(buffer3_offset.buffer), 4);
271+
expect(result.value).toBe(128 * 128 * 128 * 128 - 1);
272+
expect(result.nextOffset).toBe(8);
224273
});
225274

226275
function doRoundTripEncodeDecodeVliTest(value: number) {

0 commit comments

Comments
 (0)