lib: fix TypeError with EventEmitter#on() abuse
authorBen Noordhuis <info@bnoordhuis.nl>
Tue, 20 Jan 2015 18:30:50 +0000 (19:30 +0100)
committerBen Noordhuis <info@bnoordhuis.nl>
Tue, 20 Jan 2015 22:25:57 +0000 (23:25 +0100)
Commit 2931348 added EventEmitter#getMaxListeners() but introduced a
regression when people abuse EventEmitter.prototype.on.call() to call
EventEmitter#on() on a non-EE object.  Add a workaround for that.

Fixes: https://github.com/iojs/io.js/issues/523
PR-URL: https://github.com/iojs/io.js/pull/527
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
lib/events.js
test/parallel/test-event-emitter-get-max-listeners.js

index 2f3215a..3bc532e 100644 (file)
@@ -46,11 +46,14 @@ EventEmitter.prototype.setMaxListeners = function setMaxListeners(n) {
   return this;
 };
 
-EventEmitter.prototype.getMaxListeners = function getMaxListeners() {
-  if (!util.isUndefined(this._maxListeners))
-    return this._maxListeners;
-  else
+function $getMaxListeners(that) {
+  if (util.isUndefined(that._maxListeners))
     return EventEmitter.defaultMaxListeners;
+  return that._maxListeners;
+}
+
+EventEmitter.prototype.getMaxListeners = function getMaxListeners() {
+  return $getMaxListeners(this);
 };
 
 EventEmitter.prototype.emit = function emit(type) {
@@ -151,7 +154,7 @@ EventEmitter.prototype.addListener = function addListener(type, listener) {
 
   // Check for listener leak
   if (util.isObject(this._events[type]) && !this._events[type].warned) {
-    var m = this.getMaxListeners();
+    var m = $getMaxListeners(this);
     if (m && m > 0 && this._events[type].length > m) {
       this._events[type].warned = true;
       console.error('(node) warning: possible EventEmitter memory ' +
index bcaa70b..57430a4 100644 (file)
@@ -11,3 +11,8 @@ assert.strictEqual(emitter.getMaxListeners(), 0);
 
 emitter.setMaxListeners(3);
 assert.strictEqual(emitter.getMaxListeners(), 3);
+
+// https://github.com/iojs/io.js/issues/523 - second call should not throw.
+var recv = {};
+EventEmitter.prototype.on.call(recv, 'event', function() {});
+EventEmitter.prototype.on.call(recv, 'event', function() {});