Skip to content

Commit 388e5f5

Browse files
fix: throw upon invalid packet format
Instead of returning an ERROR packet, the decoder will now throw an error, since it means the other side is sending invalid payloads. The server will then disconnect the client: [1] [1] https://github.com/socketio/socket.io/blob/2.3.0/lib/client.js#L194-L198
1 parent f516346 commit 388e5f5

2 files changed

Lines changed: 64 additions & 14 deletions

File tree

index.js

Lines changed: 43 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,14 @@ exports.ERROR = 4;
1414
exports.BINARY_EVENT = 5;
1515
exports.BINARY_ACK = 6;
1616

17-
var errorPacket = {
18-
type: exports.ERROR,
19-
data: 'parser error'
17+
var isInteger = Number.isInteger || function (value) {
18+
return typeof value === 'number' &&
19+
isFinite(value) &&
20+
Math.floor(value) === value;
2021
};
2122

23+
var isString = function (value) { return typeof value === 'string'; };
24+
2225
function Encoder () {}
2326

2427
Encoder.prototype.encode = function (packet, callback) {
@@ -45,20 +48,46 @@ Decoder.prototype.add = function (obj) {
4548
};
4649

4750
Decoder.prototype.parseJSON = function (obj) {
48-
try {
49-
var decoded = JSON.parse(obj);
50-
this.emit('decoded', decoded);
51-
} catch (e) {
52-
this.emit('decoded', errorPacket);
53-
}
51+
var decoded = JSON.parse(obj);
52+
this.checkPacket(decoded);
53+
this.emit('decoded', decoded);
5454
};
5555

5656
Decoder.prototype.parseBinary = function (obj) {
57-
try {
58-
var decoded = msgpack.decode(obj);
59-
this.emit('decoded', decoded);
60-
} catch (e) {
61-
this.emit('decoded', errorPacket);
57+
var decoded = msgpack.decode(obj);
58+
this.checkPacket(decoded);
59+
this.emit('decoded', decoded);
60+
};
61+
62+
function isDataValid (decoded) {
63+
switch (decoded.type) {
64+
case exports.CONNECT:
65+
case exports.DISCONNECT:
66+
return decoded.data === undefined;
67+
case exports.ERROR:
68+
return isString(decoded.data);
69+
default:
70+
return Array.isArray(decoded.data);
71+
}
72+
}
73+
74+
Decoder.prototype.checkPacket = function (decoded) {
75+
var isTypeValid = isInteger(decoded.type) && decoded.type >= exports.CONNECT && decoded.type <= exports.BINARY_ACK;
76+
if (!isTypeValid) {
77+
throw new Error('invalid packet type');
78+
}
79+
80+
if (!isString(decoded.nsp)) {
81+
throw new Error('invalid namespace');
82+
}
83+
84+
if (!isDataValid(decoded)) {
85+
throw new Error('invalid payload');
86+
}
87+
88+
var isAckValid = decoded.id === undefined || isInteger(decoded.id);
89+
if (!isAckValid) {
90+
throw new Error('invalid packet id');
6291
}
6392
};
6493

test/index.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,4 +112,25 @@ describe('parser', () => {
112112
done();
113113
});
114114
});
115+
116+
it('throws an error upon invalid format', () => {
117+
const decoder = new customParser.Decoder();
118+
119+
expect(() => decoder.add('{')).to.throwError(/Unexpected end of JSON input/);
120+
expect(() => decoder.add(Buffer.from([]))).to.throwError(/Could not parse/);
121+
122+
expect(() => decoder.add('{}')).to.throwError(/invalid packet type/);
123+
expect(() => decoder.add('{"type":"a"}')).to.throwError(/invalid packet type/);
124+
expect(() => decoder.add('{"type":7}')).to.throwError(/invalid packet type/);
125+
expect(() => decoder.add(Buffer.from([1]))).to.throwError(/invalid packet type/);
126+
127+
expect(() => decoder.add('{"type":2}')).to.throwError(/invalid namespace/);
128+
expect(() => decoder.add('{"type":2,"nsp":2}')).to.throwError(/invalid namespace/);
129+
130+
expect(() => decoder.add('{"type":2,"nsp":"/"}')).to.throwError(/invalid payload/);
131+
expect(() => decoder.add('{"type":2,"nsp":"/","data":4}')).to.throwError(/invalid payload/);
132+
expect(() => decoder.add('{"type":4,"nsp":"/","data":[]}')).to.throwError(/invalid payload/);
133+
134+
expect(() => decoder.add('{"type":2,"nsp":"/","data":[],"id":"a"}')).to.throwError(/invalid packet id/);
135+
});
115136
});

0 commit comments

Comments
 (0)