Permalink
Browse files

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 #<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.<anonymous> (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 `{}`.
  • Loading branch information...
1 parent 276245d commit 440ce52535bb931d194e24517a40a0be21023857 @tricknotes committed Dec 5, 2012
Showing with 41 additions and 4 deletions.
  1. +4 −4 lib/events.js
  2. +37 −0 test/simple/test-event-emitter-prototype-property.js
View
@@ -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]];
@@ -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);
+});

0 comments on commit 440ce52

Please sign in to comment.