fix: do not modify the input packet upon encoding

Note: this issue has existed since Socket.IO v1.0 (see [1]), because
the `deconstructPacket()` method also mutates its input argument.

This also explains why some adapters (like [2]) need to use
`process.nextTick()` when extending the `broadcast()` method, because
`Adapter.broadcast()` calls `Encoder.encode()` ([3]).

Related:

- https://github.com/socketio/socket.io/issues/4374
- https://github.com/socketio/socket.io-mongo-adapter/issues/10

[1]: 299849b002
[2]: https://github.com/socketio/socket.io-postgres-adapter/blob/0.3.0/lib/index.ts#L587-L590
[3]: https://github.com/socketio/socket.io-adapter/blob/2.4.0/lib/index.ts#L148
This commit is contained in:
Damien Arrachequesne
2023-01-19 09:04:38 +01:00
parent 9143aa4c8e
commit ae8dd88995
4 changed files with 29 additions and 13 deletions

View File

@@ -53,7 +53,7 @@ function _deconstructPacket(data, buffers) {
export function reconstructPacket(packet, buffers) {
packet.data = _reconstructPacket(packet.data, buffers);
packet.attachments = undefined; // no longer useful
delete packet.attachments; // no longer useful
return packet;
}

View File

@@ -53,11 +53,15 @@ export class Encoder {
if (obj.type === PacketType.EVENT || obj.type === PacketType.ACK) {
if (hasBinary(obj)) {
obj.type =
obj.type === PacketType.EVENT
? PacketType.BINARY_EVENT
: PacketType.BINARY_ACK;
return this.encodeAsBinary(obj);
return this.encodeAsBinary({
type:
obj.type === PacketType.EVENT
? PacketType.BINARY_EVENT
: PacketType.BINARY_ACK,
nsp: obj.nsp,
data: obj.data,
id: obj.id,
});
}
}
return [this.encodeAsString(obj)];
@@ -149,10 +153,9 @@ export class Decoder extends Emitter<{}, {}, DecoderReservedEvents> {
throw new Error("got plaintext data when reconstructing a packet");
}
packet = this.decodeString(obj);
if (
packet.type === PacketType.BINARY_EVENT ||
packet.type === PacketType.BINARY_ACK
) {
const isBinaryEvent = packet.type === PacketType.BINARY_EVENT;
if (isBinaryEvent || packet.type === PacketType.BINARY_ACK) {
packet.type = isBinaryEvent ? PacketType.EVENT : PacketType.ACK;
// binary packet's json
this.reconstructor = new BinaryReconstructor(packet);