diff options
author | Brian White <mscdex@mscdex.net> | 2016-04-06 20:33:28 -0400 |
---|---|---|
committer | Brian White <mscdex@mscdex.net> | 2016-04-18 21:45:26 -0400 |
commit | e38bade82801645d8cc1010e3f4e9826052244cb (patch) | |
tree | 01ca88375556ee4864a3895ccb7a6ebea020d961 /lib/events.js | |
parent | dba245f79622c0c5877825f7cd11667be3548e8e (diff) | |
download | node-new-e38bade82801645d8cc1010e3f4e9826052244cb.tar.gz |
events: don't inherit from Object.prototype
This commit safely allows event names that are named the same as
properties that are ordinarily inherited from Object.prototype such
as __proto__.
Fixes: https://github.com/nodejs/node/issues/728
PR-URL: https://github.com/nodejs/node/pull/6092
Reviewed-By: Evan Lucas <evanlucas@me.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Diffstat (limited to 'lib/events.js')
-rw-r--r-- | lib/events.js | 20 |
1 files changed, 13 insertions, 7 deletions
diff --git a/lib/events.js b/lib/events.js index a67de552f1..669c0d70ea 100644 --- a/lib/events.js +++ b/lib/events.js @@ -2,6 +2,12 @@ var domain; +// This constructor is used to store event handlers. Instantiating this is +// faster than explicitly calling `Object.create(null)` to get a "clean" empty +// object (tested with v8 v4.9). +function EventHandlers() {} +EventHandlers.prototype = Object.create(null); + function EventEmitter() { EventEmitter.init.call(this); } @@ -44,7 +50,7 @@ EventEmitter.init = function() { } if (!this._events || this._events === Object.getPrototypeOf(this)._events) { - this._events = {}; + this._events = new EventHandlers(); this._eventsCount = 0; } @@ -211,7 +217,7 @@ EventEmitter.prototype.addListener = function addListener(type, listener) { events = this._events; if (!events) { - events = this._events = {}; + events = this._events = new EventHandlers(); this._eventsCount = 0; } else { // To avoid recursion in the case that type === "newListener"! Before @@ -296,7 +302,7 @@ EventEmitter.prototype.removeListener = if (list === listener || (list.listener && list.listener === listener)) { if (--this._eventsCount === 0) - this._events = {}; + this._events = new EventHandlers(); else { delete events[type]; if (events.removeListener) @@ -319,7 +325,7 @@ EventEmitter.prototype.removeListener = if (list.length === 1) { list[0] = undefined; if (--this._eventsCount === 0) { - this._events = {}; + this._events = new EventHandlers(); return this; } else { delete events[type]; @@ -346,11 +352,11 @@ EventEmitter.prototype.removeAllListeners = // not listening for removeListener, no need to emit if (!events.removeListener) { if (arguments.length === 0) { - this._events = {}; + this._events = new EventHandlers(); this._eventsCount = 0; } else if (events[type]) { if (--this._eventsCount === 0) - this._events = {}; + this._events = new EventHandlers(); else delete events[type]; } @@ -366,7 +372,7 @@ EventEmitter.prototype.removeAllListeners = this.removeAllListeners(key); } this.removeAllListeners('removeListener'); - this._events = {}; + this._events = new EventHandlers(); this._eventsCount = 0; return this; } |