From 181bad58d31f81e18b641b9efb79839c00f3583a Mon Sep 17 00:00:00 2001 From: Antoine du Hamel Date: Sun, 6 Dec 2020 12:04:41 +0100 Subject: [PATCH] lib: add primordials.SafeArrayIterator PR-URL: https://github.com/nodejs/node/pull/36532 Reviewed-By: Rich Trott --- lib/internal/event_target.js | 2 ++ lib/internal/modules/cjs/loader.js | 2 +- lib/internal/modules/esm/module_job.js | 9 +++++---- lib/internal/per_context/primordials.js | 7 +++++++ lib/internal/url.js | 4 ++-- lib/internal/util/debuglog.js | 5 +++-- test/parallel/test-require-delete-array-iterator.js | 13 +++++++++++++ 7 files changed, 33 insertions(+), 9 deletions(-) create mode 100644 test/parallel/test-require-delete-array-iterator.js diff --git a/lib/internal/event_target.js b/lib/internal/event_target.js index cfc138d6dbf7cf..fd29b07bf6df02 100644 --- a/lib/internal/event_target.js +++ b/lib/internal/event_target.js @@ -13,6 +13,7 @@ const { ObjectGetOwnPropertyDescriptor, ObjectGetOwnPropertyDescriptors, ReflectApply, + SafeArrayIterator, SafeMap, String, Symbol, @@ -653,6 +654,7 @@ function defineEventHandler(emitter, name) { const EventEmitterMixin = (Superclass) => { class MixedEventEmitter extends Superclass { constructor(...args) { + args = new SafeArrayIterator(args); super(...args); FunctionPrototypeCall(EventEmitter, this); } diff --git a/lib/internal/modules/cjs/loader.js b/lib/internal/modules/cjs/loader.js index 037d872e1d4fa1..b129e94d9890c0 100644 --- a/lib/internal/modules/cjs/loader.js +++ b/lib/internal/modules/cjs/loader.js @@ -462,7 +462,7 @@ function trySelf(parentPath, request) { const EXPORTS_PATTERN = /^((?:@[^/\\%]+\/)?[^./\\%][^/\\%]*)(\/.*)?$/; function resolveExports(nmPath, request) { // The implementation's behavior is meant to mirror resolution in ESM. - const [, name, expansion = ''] = + const { 1: name, 2: expansion = '' } = StringPrototypeMatch(request, EXPORTS_PATTERN) || []; if (!name) return; diff --git a/lib/internal/modules/esm/module_job.js b/lib/internal/modules/esm/module_job.js index 549d43cc20e119..5043da896622be 100644 --- a/lib/internal/modules/esm/module_job.js +++ b/lib/internal/modules/esm/module_job.js @@ -10,6 +10,7 @@ const { PromiseResolve, PromisePrototypeCatch, ReflectApply, + SafeArrayIterator, SafeSet, StringPrototypeIncludes, StringPrototypeMatch, @@ -60,9 +61,9 @@ class ModuleJob { }); if (promises !== undefined) - await PromiseAll(promises); + await PromiseAll(new SafeArrayIterator(promises)); - return PromiseAll(dependencyJobs); + return PromiseAll(new SafeArrayIterator(dependencyJobs)); }; // Promise for the list of all dependencyJobs. this.linked = link(); @@ -90,8 +91,8 @@ class ModuleJob { } jobsInGraph.add(moduleJob); const dependencyJobs = await moduleJob.linked; - return PromiseAll( - ArrayPrototypeMap(dependencyJobs, addJobsToDependencyGraph)); + return PromiseAll(new SafeArrayIterator( + ArrayPrototypeMap(dependencyJobs, addJobsToDependencyGraph))); }; await addJobsToDependencyGraph(this); diff --git a/lib/internal/per_context/primordials.js b/lib/internal/per_context/primordials.js index 68c36229825f73..7947c14cde8d39 100644 --- a/lib/internal/per_context/primordials.js +++ b/lib/internal/per_context/primordials.js @@ -242,6 +242,9 @@ primordials.SafeWeakSet = makeSafe( // Refs: https://tc39.es/ecma262/#sec-%typedarray%-intrinsic-object [ { name: 'TypedArray', original: Reflect.getPrototypeOf(Uint8Array) }, + { name: 'ArrayIterator', original: { + prototype: Reflect.getPrototypeOf(Array.prototype[Symbol.iterator]()), + } }, { name: 'StringIterator', original: { prototype: Reflect.getPrototypeOf(String.prototype[Symbol.iterator]()), } }, @@ -253,6 +256,10 @@ primordials.SafeWeakSet = makeSafe( copyPrototype(original.prototype, primordials, `${name}Prototype`); }); +primordials.SafeArrayIterator = createSafeIterator( + primordials.ArrayPrototypeSymbolIterator, + primordials.ArrayIteratorPrototypeNext +); primordials.SafeStringIterator = createSafeIterator( primordials.StringPrototypeSymbolIterator, primordials.StringIteratorPrototypeNext diff --git a/lib/internal/url.js b/lib/internal/url.js index a15f19889800c5..d718dfa9d13d1f 100644 --- a/lib/internal/url.js +++ b/lib/internal/url.js @@ -446,8 +446,8 @@ ObjectDefineProperties(URL.prototype, { if (ctx.host === null && ctx.path.length > 1 && ctx.path[0] === '') { ret += '/.'; } - for (const segment of ctx.path) { - ret += '/' + segment; + if (ctx.path.length) { + ret += '/' + ArrayPrototypeJoin(ctx.path, '/'); } } if (options.search && ctx.query !== null) diff --git a/lib/internal/util/debuglog.js b/lib/internal/util/debuglog.js index a3b8a84772054e..46d3ed5613246e 100644 --- a/lib/internal/util/debuglog.js +++ b/lib/internal/util/debuglog.js @@ -6,6 +6,7 @@ const { ObjectDefineProperty, RegExp, RegExpPrototypeTest, + SafeArrayIterator, StringPrototypeToUpperCase } = primordials; @@ -78,7 +79,7 @@ function debuglog(set, cb) { debug = debuglogImpl(enabled, set); if (typeof cb === 'function') cb(debug); - debug(...args); + debug(...new SafeArrayIterator(args)); }; let enabled; let test = () => { @@ -86,7 +87,7 @@ function debuglog(set, cb) { test = () => enabled; return enabled; }; - const logger = (...args) => debug(...args); + const logger = (...args) => debug(...new SafeArrayIterator(args)); ObjectDefineProperty(logger, 'enabled', { get() { return test(); diff --git a/test/parallel/test-require-delete-array-iterator.js b/test/parallel/test-require-delete-array-iterator.js new file mode 100644 index 00000000000000..5424ef8b75da9d --- /dev/null +++ b/test/parallel/test-require-delete-array-iterator.js @@ -0,0 +1,13 @@ +'use strict'; + +const common = require('../common'); + + +const ArrayIteratorPrototype = + Object.getPrototypeOf(Array.prototype[Symbol.iterator]()); + +delete Array.prototype[Symbol.iterator]; +delete ArrayIteratorPrototype.next; + +require('../common/fixtures'); +import('../fixtures/es-modules/test-esm-ok.mjs').then(common.mustCall());