Skip to content

Commit

Permalink
fix: check the format of the event name
Browse files Browse the repository at this point in the history
A packet like '2[{"toString":"foo"}]' was decoded as:

{
  type: EVENT,
  data: [ { "toString": "foo" } ]
}

Which would then throw an error when passed to the EventEmitter class:

> TypeError: Cannot convert object to primitive value
>    at Socket.emit (node:events:507:25)
>    at .../node_modules/socket.io/lib/socket.js:531:14

History of the isPayloadValid() method:

- added in [78f9fc2](78f9fc2) (v4.0.1, socket.io@3.0.0)
- updated in [1c220dd](1c220dd) (v4.0.4, socket.io@3.1.0)

Backported from 3b78117
  • Loading branch information
darrachequesne committed May 22, 2023
1 parent 4b3c191 commit 2dc3c92
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 11 deletions.
25 changes: 22 additions & 3 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -329,11 +329,10 @@ function decodeString(str) {
// look up json data
if (str.charAt(++i)) {
var payload = tryParse(str.substr(i));
var isPayloadValid = payload !== false && (p.type === exports.ERROR || isArray(payload));
if (isPayloadValid) {
if (isPayloadValid(p.type, payload)) {
p.data = payload;
} else {
return error('invalid payload');
throw new Error("invalid payload");
}
}

Expand All @@ -349,6 +348,26 @@ function tryParse(str) {
}
}

function isPayloadValid(type, payload) {
switch (type) {
case 0: // CONNECT
return typeof payload === "object";
case 1: // DISCONNECT
return payload === undefined;
case 4: // ERROR
return typeof payload === "string" || typeof payload === "object";
case 2: // EVENT
case 5: // BINARY_EVENT
return (
isArray(payload) &&
(typeof payload[0] === "string" || typeof payload[0] === "number")
);
case 3: // ACK
case 6: // BINARY_ACK
return isArray(payload);
}
}

/**
* Deallocates a parser's resources
*
Expand Down
2 changes: 1 addition & 1 deletion test/arraybuffer.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ describe('parser', function() {
it('cleans itself up on close', function() {
var packet = {
type: parser.BINARY_EVENT,
data: [new ArrayBuffer(2), new ArrayBuffer(3)],
data: ["foo", new ArrayBuffer(2), new ArrayBuffer(3)],
id: 0,
nsp: '/'
};
Expand Down
22 changes: 15 additions & 7 deletions test/parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,12 +86,20 @@ describe('parser', function(){
}
});

it('returns an error packet on parsing error', function(done){
var decoder = new parser.Decoder();
decoder.on('decoded', function(packet) {
expect(packet).to.eql({ type: 4, data: 'parser error: invalid payload' });
done();
});
decoder.add('442["some","data"');
it('returns an error packet on parsing error', function(){
function isInvalidPayload (str) {
expect(function () {
new parser.Decoder().add(str)
}).to.throwException(/^invalid payload$/);
}

isInvalidPayload('442["some","data"');
isInvalidPayload('0/admin,"invalid"');
isInvalidPayload("1/admin,{}");
isInvalidPayload('2/admin,"invalid');
isInvalidPayload("2/admin,{}");
isInvalidPayload('2[{"toString":"foo"}]');
isInvalidPayload('2[true,"foo"]');
isInvalidPayload('2[null,"bar"]');
});
});

0 comments on commit 2dc3c92

Please sign in to comment.