Skip to content

Commit 4bd5b23

Browse files
committedOct 13, 2020
feat: throw upon reserved event names
These events cannot be used by the end users, because they are part of the Socket.IO public API, so using them will now throw an error explicitly.
1 parent a8c0600 commit 4bd5b23

File tree

6 files changed

+46
-49
lines changed

6 files changed

+46
-49
lines changed
 

‎dist/namespace.js

+2-11
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,6 @@ const socket_io_parser_1 = require("socket.io-parser");
1010
const has_binary2_1 = __importDefault(require("has-binary2"));
1111
const debug_1 = __importDefault(require("debug"));
1212
const debug = debug_1.default("socket.io:namespace");
13-
/**
14-
* Blacklisted events.
15-
*/
16-
const events = [
17-
"connect",
18-
"connection",
19-
"newListener"
20-
];
2113
class Namespace extends events_1.EventEmitter {
2214
/**
2315
* Namespace constructor.
@@ -158,9 +150,8 @@ class Namespace extends events_1.EventEmitter {
158150
*/
159151
// @ts-ignore
160152
emit(ev, ...args) {
161-
if (~events.indexOf(ev)) {
162-
super.emit.apply(this, arguments);
163-
return this;
153+
if (socket_1.RESERVED_EVENTS.has(ev)) {
154+
throw new Error(`"${ev}" is a reserved event name`);
164155
}
165156
// set up packet object
166157
args.unshift(ev);

‎dist/socket.d.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { Client } from "./client";
44
import { Namespace } from "./namespace";
55
import { IncomingMessage } from "http";
66
import { Room, SocketId } from "socket.io-adapter";
7+
export declare const RESERVED_EVENTS: Set<string>;
78
/**
89
* The handshake details
910
*/
@@ -76,7 +77,7 @@ export declare class Socket extends EventEmitter {
7677
*
7778
* @return {Socket} self
7879
*/
79-
emit(ev: any): this;
80+
emit(ev: string, ...args: any[]): this;
8081
/**
8182
* Targets a room when broadcasting.
8283
*

‎dist/socket.js

+8-11
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,23 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
33
return (mod && mod.__esModule) ? mod : { "default": mod };
44
};
55
Object.defineProperty(exports, "__esModule", { value: true });
6-
exports.Socket = void 0;
6+
exports.Socket = exports.RESERVED_EVENTS = void 0;
77
const events_1 = require("events");
88
const socket_io_parser_1 = require("socket.io-parser");
99
const has_binary2_1 = __importDefault(require("has-binary2"));
1010
const url_1 = __importDefault(require("url"));
1111
const debug_1 = __importDefault(require("debug"));
1212
const base64id_1 = __importDefault(require("base64id"));
1313
const debug = debug_1.default("socket.io:socket");
14-
/**
15-
* Blacklisted events.
16-
*/
17-
const events = [
14+
exports.RESERVED_EVENTS = new Set([
1815
"error",
1916
"connect",
2017
"disconnect",
2118
"disconnecting",
19+
// EventEmitter reserved events: https://nodejs.org/api/events.html#events_event_newlistener
2220
"newListener",
2321
"removeListener"
24-
];
22+
]);
2523
class Socket extends events_1.EventEmitter {
2624
/**
2725
* Interface to a `Client` for a given `Namespace`.
@@ -69,12 +67,11 @@ class Socket extends events_1.EventEmitter {
6967
* @return {Socket} self
7068
*/
7169
// @ts-ignore
72-
emit(ev) {
73-
if (~events.indexOf(ev)) {
74-
super.emit.apply(this, arguments);
75-
return this;
70+
emit(ev, ...args) {
71+
if (exports.RESERVED_EVENTS.has(ev)) {
72+
throw new Error(`"${ev}" is a reserved event name`);
7673
}
77-
const args = Array.prototype.slice.call(arguments);
74+
args.unshift(ev);
7875
const packet = {
7976
type: (this.flags.binary !== undefined
8077
? this.flags.binary

‎lib/namespace.ts

+3-14
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Socket } from "./socket";
1+
import { Socket, RESERVED_EVENTS } from "./socket";
22
import { Server } from "./index";
33
import { Client } from "./client";
44
import { EventEmitter } from "events";
@@ -9,16 +9,6 @@ import { Adapter, Room, SocketId } from "socket.io-adapter";
99

1010
const debug = debugModule("socket.io:namespace");
1111

12-
/**
13-
* Blacklisted events.
14-
*/
15-
16-
const events = [
17-
"connect", // for symmetry with client
18-
"connection",
19-
"newListener"
20-
];
21-
2212
export class Namespace extends EventEmitter {
2313
public readonly name: string;
2414
public readonly connected: Map<SocketId, Socket> = new Map();
@@ -176,9 +166,8 @@ export class Namespace extends EventEmitter {
176166
*/
177167
// @ts-ignore
178168
public emit(ev: string, ...args: any[]): Namespace {
179-
if (~events.indexOf(ev)) {
180-
super.emit.apply(this, arguments);
181-
return this;
169+
if (RESERVED_EVENTS.has(ev)) {
170+
throw new Error(`"${ev}" is a reserved event name`);
182171
}
183172
// set up packet object
184173
args.unshift(ev);

‎lib/socket.ts

+7-12
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,15 @@ import base64id from "base64id";
1212

1313
const debug = debugModule("socket.io:socket");
1414

15-
/**
16-
* Blacklisted events.
17-
*/
18-
19-
const events = [
15+
export const RESERVED_EVENTS = new Set([
2016
"error",
2117
"connect",
2218
"disconnect",
2319
"disconnecting",
20+
// EventEmitter reserved events: https://nodejs.org/api/events.html#events_event_newlistener
2421
"newListener",
2522
"removeListener"
26-
];
23+
]);
2724

2825
/**
2926
* The handshake details
@@ -133,13 +130,11 @@ export class Socket extends EventEmitter {
133130
* @return {Socket} self
134131
*/
135132
// @ts-ignore
136-
public emit(ev) {
137-
if (~events.indexOf(ev)) {
138-
super.emit.apply(this, arguments);
139-
return this;
133+
public emit(ev: string, ...args: any[]) {
134+
if (RESERVED_EVENTS.has(ev)) {
135+
throw new Error(`"${ev}" is a reserved event name`);
140136
}
141-
142-
const args = Array.prototype.slice.call(arguments);
137+
args.unshift(ev);
143138
const packet: any = {
144139
type: (this.flags.binary !== undefined
145140
? this.flags.binary

‎test/socket.io.ts

+24
Original file line numberDiff line numberDiff line change
@@ -693,6 +693,14 @@ describe("socket.io", () => {
693693
});
694694
});
695695

696+
it("should throw on reserved event", () => {
697+
const sio = new Server();
698+
699+
expect(() => sio.emit("connect")).to.throwException(
700+
/"connect" is a reserved event name/
701+
);
702+
});
703+
696704
describe("dynamic namespaces", () => {
697705
it("should allow connections to dynamic namespaces with a regex", done => {
698706
const srv = createServer();
@@ -1657,6 +1665,22 @@ describe("socket.io", () => {
16571665
});
16581666
});
16591667
});
1668+
1669+
it("should throw on reserved event", done => {
1670+
const srv = createServer();
1671+
const sio = new Server(srv);
1672+
1673+
srv.listen(() => {
1674+
const socket = client(srv);
1675+
sio.on("connection", s => {
1676+
expect(() => s.emit("error")).to.throwException(
1677+
/"error" is a reserved event name/
1678+
);
1679+
socket.close();
1680+
done();
1681+
});
1682+
});
1683+
});
16601684
});
16611685

16621686
describe("messaging many", () => {

0 commit comments

Comments
 (0)
Please sign in to comment.