From 440ce52535bb931d194e24517a40a0be21023857 Mon Sep 17 00:00:00 2001 From: Ryunosuke SATO Date: Wed, 5 Dec 2012 13:40:59 +0900 Subject: [PATCH] events: Support prototype property name as an event type The prototype name (such as '__proto__') as an event type does not work as my expectation. ``` > var events = require('events') > var e = new events.EventEmitter(); > e.on('__proto__', function() {}); > e.emit('__proto__'); TypeError: Object # has no method 'apply' at EventEmitter.emit (events.js:126:20) at repl:1:3 at REPLServer.self.eval (repl.js:109:21) at rli.on.self.bufferedCmd (repl.js:258:20) at REPLServer.self.eval (repl.js:116:5) at Interface. (repl.js:248:12) at Interface.EventEmitter.emit (events.js:96:17) at Interface._onLine (readline.js:200:10) at Interface._line (readline.js:518:8) at Interface._ttyWrite (readline.js:736:14) ``` To support these, use `Object.create(null)` instead of `{}`. --- lib/events.js | 8 ++-- .../test-event-emitter-prototype-property.js | 37 +++++++++++++++++++ 2 files changed, 41 insertions(+), 4 deletions(-) create mode 100644 test/simple/test-event-emitter-prototype-property.js diff --git a/lib/events.js b/lib/events.js index 017df7504cb..2683cc8ad87 100644 --- a/lib/events.js +++ b/lib/events.js @@ -44,7 +44,7 @@ exports.EventEmitter = EventEmitter; // that to be increased. Set to zero for unlimited. var defaultMaxListeners = 10; EventEmitter.prototype.setMaxListeners = function(n) { - if (!this._events) this._events = {}; + if (!this._events) this._events = Object.create(null); this._maxListeners = n; }; @@ -140,7 +140,7 @@ EventEmitter.prototype.addListener = function(type, listener) { throw new Error('addListener only takes instances of Function'); } - if (!this._events) this._events = {}; + if (!this._events) this._events = Object.create(null); // To avoid recursion in the case that type == "newListeners"! Before // adding it to the listeners, first emit "newListeners". @@ -234,7 +234,7 @@ EventEmitter.prototype.removeListener = function(type, listener) { EventEmitter.prototype.removeAllListeners = function(type) { if (arguments.length === 0) { - this._events = {}; + this._events = Object.create(null); return this; } @@ -244,7 +244,7 @@ EventEmitter.prototype.removeAllListeners = function(type) { }; EventEmitter.prototype.listeners = function(type) { - if (!this._events) this._events = {}; + if (!this._events) this._events = Object.create(null); if (!this._events[type]) this._events[type] = []; if (!isArray(this._events[type])) { this._events[type] = [this._events[type]]; diff --git a/test/simple/test-event-emitter-prototype-property.js b/test/simple/test-event-emitter-prototype-property.js new file mode 100644 index 00000000000..a5d8a7d04a1 --- /dev/null +++ b/test/simple/test-event-emitter-prototype-property.js @@ -0,0 +1,37 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +var common = require('../common'); +var assert = require('assert'); +var events = require('events'); + +var e = new events.EventEmitter(); + +var emited = false; +e.on('__proto__', function() { + emited = true; +}); + +e.emit('__proto__'); + +process.on('exit', function() { + assert.equal(true, emited); +});