Skip to content

Commit

Permalink
refactor: export a function to validate the format of a packet
Browse files Browse the repository at this point in the history
  • Loading branch information
darrachequesne committed May 31, 2023
1 parent d9db473 commit 7c1632f
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 3 deletions.
47 changes: 45 additions & 2 deletions lib/index.ts
Expand Up @@ -280,11 +280,11 @@ export class Decoder extends Emitter<{}, {}, DecoderReservedEvents> {
private static isPayloadValid(type: PacketType, payload: any): boolean {
switch (type) {
case PacketType.CONNECT:
return typeof payload === "object";
return isObject(payload);
case PacketType.DISCONNECT:
return payload === undefined;
case PacketType.CONNECT_ERROR:
return typeof payload === "string" || typeof payload === "object";
return typeof payload === "string" || isObject(payload);
case PacketType.EVENT:
case PacketType.BINARY_EVENT:
return (
Expand Down Expand Up @@ -354,3 +354,46 @@ class BinaryReconstructor {
this.buffers = [];
}
}

export function isPacketValid(packet: Packet): boolean {
return (
isNamespaceValid(packet) &&
isAckIdValid(packet) &&
isPayloadValid(packet.type, packet.data)
);
}

function isNamespaceValid(packet: Packet): boolean {
return typeof packet.nsp === "string";
}

function isAckIdValid(packet: Packet) {
return packet.id === undefined || Number.isInteger(packet.id);
}

// see https://stackoverflow.com/questions/8511281/check-if-a-value-is-an-object-in-javascript
function isObject(value: any): boolean {
return Object.prototype.toString.call(value) === "[object Object]";
}

function isPayloadValid(type: PacketType, payload: any): boolean {
switch (type) {
case PacketType.CONNECT:
return payload === undefined || isObject(payload);
case PacketType.DISCONNECT:
return payload === undefined;
case PacketType.EVENT:
return (
Array.isArray(payload) &&
(typeof payload[0] === "number" ||
(typeof payload[0] === "string" &&
RESERVED_EVENTS.indexOf(payload[0]) === -1))
);
case PacketType.ACK:
return Array.isArray(payload);
case PacketType.CONNECT_ERROR:
return typeof payload === "string" || isObject(payload);
default:
return false;
}
}
27 changes: 26 additions & 1 deletion test/parser.js
@@ -1,4 +1,9 @@
const { PacketType, Decoder, Encoder } = require("..");
const {
PacketType,
Decoder,
Encoder,
isPacketValid,
} = require("..");
const expect = require("expect.js");
const helpers = require("./helpers.js");

Expand Down Expand Up @@ -147,4 +152,24 @@ describe("socket.io-parser", () => {
decoder.add('2["hello"]');
});
});

it("should ensure that a packet is valid", () => {
expect(isPacketValid({ type: 0, nsp: "/" })).to.eql(true);
expect(isPacketValid({ type: 0, nsp: "/", data: { foo: "bar" } })).to.eql(true);
expect(isPacketValid({ type: 1, nsp: "/" })).to.eql(true);
expect(isPacketValid({ type: 2, nsp: "/", data: ["foo"] })).to.eql(true);
expect(isPacketValid({ type: 2, nsp: "/", data: [1] })).to.eql(true);
expect(isPacketValid({ type: 3, nsp: "/", id: 1, data: ["foo"] })).to.eql(true);
expect(isPacketValid({ type: 4, nsp: "/", data: "foo" })).to.eql(true);
expect(isPacketValid({ type: 4, nsp: "/", data: { foo: "bar" } })).to.eql(true);

expect(isPacketValid({ type: 9, nsp: "/" })).to.eql(false);
expect(isPacketValid({ type: 0 })).to.eql(false);
expect(isPacketValid({ type: 0, nsp: 1 })).to.eql(false);
expect(isPacketValid({ type: 0, nsp: "/", data: ["foo"] })).to.eql(false);
expect(isPacketValid({ type: 1, nsp: "/", data: ["foo"] })).to.eql(false);
expect(isPacketValid({ type: 2, nsp: "/", data: { foo: "bar" } })).to.eql(false);
expect(isPacketValid({ type: 3, nsp: "/", id: "1", data: ["foo"] })).to.eql(false);
expect(isPacketValid({ type: 4, nsp: "/" })).to.eql(false);
});
});

0 comments on commit 7c1632f

Please sign in to comment.