From d13628f9c19856d0a3376ad4fbd269b51cb322a9 Mon Sep 17 00:00:00 2001 From: Akhil Marsonya Date: Fri, 16 Apr 2021 22:47:20 +0530 Subject: [PATCH] events: refactor to use primordials in lib/events Replace code that's vulnerable to Prototype Pollution with Primordials. --- lib/events.js | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/lib/events.js b/lib/events.js index 7d219606a28b1b..e35033d45eab21 100644 --- a/lib/events.js +++ b/lib/events.js @@ -22,10 +22,16 @@ 'use strict'; const { + ArrayPrototypeIndexOf, + ArrayPrototypeJoin, + ArrayPrototypeShift, ArrayPrototypeSlice, + ArrayPrototypeSplice, Boolean, Error, ErrorCaptureStackTrace, + FunctionPrototypeBind, + FunctionPrototypeCall, MathMin, NumberIsNaN, ObjectCreate, @@ -38,9 +44,10 @@ const { PromiseResolve, ReflectOwnKeys, String, + StringPrototypeSplit, Symbol, SymbolFor, - SymbolAsyncIterator + SymbolAsyncIterator, } = primordials; const kRejection = SymbolFor('nodejs.rejection'); @@ -270,7 +277,7 @@ EventEmitter.prototype.getMaxListeners = function getMaxListeners() { function identicalSequenceRange(a, b) { for (let i = 0; i < a.length - 3; i++) { // Find the first entry of b that matches the current entry of a. - const pos = b.indexOf(a[i]); + const pos = ArrayPrototypeIndexOf(b, a[i]); if (pos !== -1) { const rest = b.length - pos; if (rest > 3) { @@ -299,16 +306,18 @@ function enhanceStackTrace(err, own) { } catch {} const sep = `\nEmitted 'error' event${ctorInfo} at:\n`; - const errStack = err.stack.split('\n').slice(1); - const ownStack = own.stack.split('\n').slice(1); + const errStack = ArrayPrototypeSlice( + StringPrototypeSplit(err.stack, '\n'), 1); + const ownStack = ArrayPrototypeSlice( + StringPrototypeSplit(own.stack, '\n'), 1); const { 0: len, 1: off } = identicalSequenceRange(ownStack, errStack); if (len > 0) { - ownStack.splice(off + 1, len - 2, - ' [... lines matching original stack trace ...]'); + ArrayPrototypeSplice(ownStack, off + 1, len - 2, + ' [... lines matching original stack trace ...]'); } - return err.stack + sep + ownStack.join('\n'); + return err.stack + sep + ArrayPrototypeJoin(ownStack, '\n'); } EventEmitter.prototype.emit = function emit(type, ...args) { @@ -332,7 +341,7 @@ EventEmitter.prototype.emit = function emit(type, ...args) { const capture = {}; ErrorCaptureStackTrace(capture, EventEmitter.prototype.emit); ObjectDefineProperty(er, kEnhanceStackBeforeInspector, { - value: enhanceStackTrace.bind(this, er, capture), + value: FunctionPrototypeBind(enhanceStackTrace, this, er, capture), configurable: true }); } catch {} @@ -625,7 +634,7 @@ EventEmitter.listenerCount = function(emitter, type) { if (typeof emitter.listenerCount === 'function') { return emitter.listenerCount(type); } - return listenerCount.call(emitter, type); + return FunctionPrototypeCall(listenerCount, emitter, type); }; EventEmitter.prototype.listenerCount = listenerCount; @@ -863,7 +872,7 @@ function on(emitter, event, options) { } function eventHandler(...args) { - const promise = unconsumedPromises.shift(); + const promise = ArrayPrototypeShift(unconsumedPromises); if (promise) { promise.resolve(createIterResult(args, false)); } else { @@ -874,7 +883,7 @@ function on(emitter, event, options) { function errorHandler(err) { finished = true; - const toError = unconsumedPromises.shift(); + const toError = ArrayPrototypeShift(unconsumedPromises); if (toError) { toError.reject(err);