From bf22f114a6e049744866ebaba48faec2cb86549b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Mon, 7 Feb 2022 13:54:32 +0100 Subject: [PATCH] refactor: update runtime code for primordial check for iterators (#13510) --- ext/console/02_console.js | 25 ++++++++++++------ ext/crypto/01_webidl.js | 39 +++++++++++++++-------------- ext/fetch/20_headers.js | 6 ++++- ext/fetch/23_request.js | 5 +++- ext/fetch/23_response.js | 13 +++++++--- ext/fetch/26_fetch.js | 5 ++-- ext/timers/01_timers.js | 7 +++++- ext/url/00_url.js | 8 +++++- ext/web/00_infra.js | 19 +++++++++++--- ext/web/02_event.js | 11 ++++---- ext/web/05_base64.js | 26 +++++++++++-------- ext/web/10_filereader.js | 7 +++++- ext/webgpu/01_webgpu.js | 7 ++++-- ext/websocket/02_websocketstream.js | 9 ++++++- ext/webstorage/01_webstorage.js | 3 ++- runtime/js/06_util.js | 6 ++++- runtime/js/40_testing.js | 10 +++++--- 17 files changed, 141 insertions(+), 65 deletions(-) diff --git a/ext/console/02_console.js b/ext/console/02_console.js index 3020c0794b..8102707b5d 100644 --- a/ext/console/02_console.js +++ b/ext/console/02_console.js @@ -53,6 +53,8 @@ RegExpPrototype, RegExpPrototypeTest, RegExpPrototypeToString, + SafeArrayIterator, + SafeSet, SetPrototype, SetPrototypeEntries, Symbol, @@ -1938,11 +1940,14 @@ const [first, ...rest] = args; if (typeof first === "string") { - this.error(`Assertion failed: ${first}`, ...rest); + this.error( + `Assertion failed: ${first}`, + ...new SafeArrayIterator(rest), + ); return; } - this.error(`Assertion failed:`, ...args); + this.error(`Assertion failed:`, ...new SafeArrayIterator(args)); }; count = (label = "default") => { @@ -1994,7 +1999,7 @@ const indexKey = isSet || isMap ? "(iter idx)" : "(idx)"; if (isSet) { - resultData = [...data]; + resultData = [...new SafeSet(data)]; } else if (isMap) { let idx = 0; resultData = {}; @@ -2048,12 +2053,16 @@ const headerKeys = ObjectKeys(objectValues); const bodyValues = ObjectValues(objectValues); + const headerProps = properties || + [ + ...new SafeArrayIterator(headerKeys), + !isMap && hasPrimitives && valuesKey, + ]; const header = ArrayPrototypeFilter([ indexKey, - ...(properties || - [...headerKeys, !isMap && hasPrimitives && valuesKey]), + ...new SafeArrayIterator(headerProps), ], Boolean); - const body = [indexKeys, ...bodyValues, values]; + const body = [indexKeys, ...new SafeArrayIterator(bodyValues), values]; toTable(header, body); }; @@ -2080,7 +2089,7 @@ const startTime = MapPrototypeGet(timerMap, label); const duration = DateNow() - startTime; - this.info(`${label}: ${duration}ms`, ...args); + this.info(`${label}: ${duration}ms`, ...new SafeArrayIterator(args)); }; timeEnd = (label = "default") => { @@ -2100,7 +2109,7 @@ group = (...label) => { if (label.length > 0) { - this.log(...label); + this.log(...new SafeArrayIterator(label)); } this.indentLevel += 2; }; diff --git a/ext/crypto/01_webidl.js b/ext/crypto/01_webidl.js index 7396487668..05c79373c7 100644 --- a/ext/crypto/01_webidl.js +++ b/ext/crypto/01_webidl.js @@ -13,6 +13,7 @@ ArrayBufferIsView, ArrayBufferPrototype, ObjectPrototypeIsPrototypeOf, + SafeArrayIterator, } = window.__bootstrap.primordials; webidl.converters.AlgorithmIdentifier = (V, opts) => { @@ -79,7 +80,7 @@ /** @type {__bootstrap.webidl.Dictionary} */ const dictRsaKeyGenParams = [ - ...dictAlgorithm, + ...new SafeArrayIterator(dictAlgorithm), { key: "modulusLength", converter: (V, opts) => @@ -97,7 +98,7 @@ .createDictionaryConverter("RsaKeyGenParams", dictRsaKeyGenParams); const dictRsaHashedKeyGenParams = [ - ...dictRsaKeyGenParams, + ...new SafeArrayIterator(dictRsaKeyGenParams), { key: "hash", converter: webidl.converters.HashAlgorithmIdentifier, @@ -111,7 +112,7 @@ ); const dictRsaHashedImportParams = [ - ...dictAlgorithm, + ...new SafeArrayIterator(dictAlgorithm), { key: "hash", converter: webidl.converters.HashAlgorithmIdentifier, @@ -127,7 +128,7 @@ webidl.converters.NamedCurve = webidl.converters.DOMString; const dictEcKeyImportParams = [ - ...dictAlgorithm, + ...new SafeArrayIterator(dictAlgorithm), { key: "namedCurve", converter: webidl.converters.NamedCurve, @@ -141,7 +142,7 @@ ); const dictEcKeyGenParams = [ - ...dictAlgorithm, + ...new SafeArrayIterator(dictAlgorithm), { key: "namedCurve", converter: webidl.converters.NamedCurve, @@ -153,7 +154,7 @@ .createDictionaryConverter("EcKeyGenParams", dictEcKeyGenParams); const dictEcImportParams = [ - ...dictAlgorithm, + ...new SafeArrayIterator(dictAlgorithm), { key: "namedCurve", converter: webidl.converters.NamedCurve, @@ -165,7 +166,7 @@ .createDictionaryConverter("EcImportParams", dictEcImportParams); const dictAesKeyGenParams = [ - ...dictAlgorithm, + ...new SafeArrayIterator(dictAlgorithm), { key: "length", converter: (V, opts) => @@ -178,7 +179,7 @@ .createDictionaryConverter("AesKeyGenParams", dictAesKeyGenParams); const dictHmacKeyGenParams = [ - ...dictAlgorithm, + ...new SafeArrayIterator(dictAlgorithm), { key: "hash", converter: webidl.converters.HashAlgorithmIdentifier, @@ -195,7 +196,7 @@ .createDictionaryConverter("HmacKeyGenParams", dictHmacKeyGenParams); const dictRsaPssParams = [ - ...dictAlgorithm, + ...new SafeArrayIterator(dictAlgorithm), { key: "saltLength", converter: (V, opts) => @@ -208,7 +209,7 @@ .createDictionaryConverter("RsaPssParams", dictRsaPssParams); const dictRsaOaepParams = [ - ...dictAlgorithm, + ...new SafeArrayIterator(dictAlgorithm), { key: "label", converter: webidl.converters["BufferSource"], @@ -219,7 +220,7 @@ .createDictionaryConverter("RsaOaepParams", dictRsaOaepParams); const dictEcdsaParams = [ - ...dictAlgorithm, + ...new SafeArrayIterator(dictAlgorithm), { key: "hash", converter: webidl.converters.HashAlgorithmIdentifier, @@ -231,7 +232,7 @@ .createDictionaryConverter("EcdsaParams", dictEcdsaParams); const dictHmacImportParams = [ - ...dictAlgorithm, + ...new SafeArrayIterator(dictAlgorithm), { key: "hash", converter: webidl.converters.HashAlgorithmIdentifier, @@ -357,7 +358,7 @@ ); const dictHkdfParams = [ - ...dictAlgorithm, + ...new SafeArrayIterator(dictAlgorithm), { key: "hash", converter: webidl.converters.HashAlgorithmIdentifier, @@ -379,7 +380,7 @@ .createDictionaryConverter("HkdfParams", dictHkdfParams); const dictPbkdf2Params = [ - ...dictAlgorithm, + ...new SafeArrayIterator(dictAlgorithm), { key: "hash", converter: webidl.converters.HashAlgorithmIdentifier, @@ -402,7 +403,7 @@ .createDictionaryConverter("Pbkdf2Params", dictPbkdf2Params); const dictAesDerivedKeyParams = [ - ...dictAlgorithm, + ...new SafeArrayIterator(dictAlgorithm), { key: "length", converter: (V, opts) => @@ -412,7 +413,7 @@ ]; const dictAesCbcParams = [ - ...dictAlgorithm, + ...new SafeArrayIterator(dictAlgorithm), { key: "iv", converter: webidl.converters["BufferSource"], @@ -421,7 +422,7 @@ ]; const dictAesGcmParams = [ - ...dictAlgorithm, + ...new SafeArrayIterator(dictAlgorithm), { key: "iv", converter: webidl.converters["BufferSource"], @@ -439,7 +440,7 @@ ]; const dictAesCtrParams = [ - ...dictAlgorithm, + ...new SafeArrayIterator(dictAlgorithm), { key: "counter", converter: webidl.converters["BufferSource"], @@ -485,7 +486,7 @@ .createDictionaryConverter("CryptoKeyPair", dictCryptoKeyPair); const dictEcdhKeyDeriveParams = [ - ...dictAlgorithm, + ...new SafeArrayIterator(dictAlgorithm), { key: "public", converter: webidl.converters.CryptoKey, diff --git a/ext/fetch/20_headers.js b/ext/fetch/20_headers.js index 94f68df420..e8a658d67b 100644 --- a/ext/fetch/20_headers.js +++ b/ext/fetch/20_headers.js @@ -32,6 +32,7 @@ ObjectPrototypeHasOwnProperty, ObjectEntries, RegExpPrototypeTest, + SafeArrayIterator, Symbol, SymbolFor, SymbolIterator, @@ -230,7 +231,10 @@ } return ArrayPrototypeSort( - [...ObjectEntries(headers), ...cookies], + [ + ...new SafeArrayIterator(ObjectEntries(headers)), + ...new SafeArrayIterator(cookies), + ], (a, b) => { const akey = a[0]; const bkey = b[0]; diff --git a/ext/fetch/23_request.js b/ext/fetch/23_request.js index 5294009ffb..1ffdd2a60d 100644 --- a/ext/fetch/23_request.js +++ b/ext/fetch/23_request.js @@ -38,6 +38,7 @@ ObjectKeys, ObjectPrototypeIsPrototypeOf, RegExpPrototypeTest, + SafeArrayIterator, Symbol, SymbolFor, TypeError, @@ -101,7 +102,9 @@ */ function cloneInnerRequest(request) { const headerList = [ - ...ArrayPrototypeMap(request.headerList, (x) => [x[0], x[1]]), + ...new SafeArrayIterator( + ArrayPrototypeMap(request.headerList, (x) => [x[0], x[1]]), + ), ]; let body = null; if (request.body !== null) { diff --git a/ext/fetch/23_response.js b/ext/fetch/23_response.js index 14aadbaf24..4dc56dd8f2 100644 --- a/ext/fetch/23_response.js +++ b/ext/fetch/23_response.js @@ -37,6 +37,7 @@ RangeError, RegExp, RegExpPrototypeTest, + SafeArrayIterator, Symbol, SymbolFor, TypeError, @@ -45,7 +46,11 @@ const VCHAR = ["\x21-\x7E"]; const OBS_TEXT = ["\x80-\xFF"]; - const REASON_PHRASE = [...HTTP_TAB_OR_SPACE, ...VCHAR, ...OBS_TEXT]; + const REASON_PHRASE = [ + ...new SafeArrayIterator(HTTP_TAB_OR_SPACE), + ...new SafeArrayIterator(VCHAR), + ...new SafeArrayIterator(OBS_TEXT), + ]; const REASON_PHRASE_MATCHER = regexMatcher(REASON_PHRASE); const REASON_PHRASE_RE = new RegExp(`^[${REASON_PHRASE_MATCHER}]*$`); @@ -90,9 +95,11 @@ * @returns {InnerResponse} */ function cloneInnerResponse(response) { - const urlList = [...response.urlList]; + const urlList = [...new SafeArrayIterator(response.urlList)]; const headerList = [ - ...ArrayPrototypeMap(response.headerList, (x) => [x[0], x[1]]), + ...new SafeArrayIterator( + ArrayPrototypeMap(response.headerList, (x) => [x[0], x[1]]), + ), ]; let body = null; if (response.body !== null) { diff --git a/ext/fetch/26_fetch.js b/ext/fetch/26_fetch.js index 0c58bbf97f..bbcbb44f0f 100644 --- a/ext/fetch/26_fetch.js +++ b/ext/fetch/26_fetch.js @@ -38,6 +38,7 @@ Promise, PromisePrototypeThen, PromisePrototypeCatch, + SafeArrayIterator, String, StringPrototypeStartsWith, StringPrototypeToLowerCase, @@ -168,7 +169,7 @@ if (this.urlList.length == 0) return null; return this.urlList[this.urlList.length - 1]; }, - urlList: recursive ? [] : [...req.urlList], + urlList: recursive ? [] : [...new SafeArrayIterator(req.urlList)], }; } @@ -331,7 +332,7 @@ if (recursive) return response; if (response.urlList.length === 0) { - response.urlList = [...req.urlList]; + response.urlList = [...new SafeArrayIterator(req.urlList)]; } return response; diff --git a/ext/timers/01_timers.js b/ext/timers/01_timers.js index caa490e614..a0b1deb457 100644 --- a/ext/timers/01_timers.js +++ b/ext/timers/01_timers.js @@ -17,6 +17,7 @@ NumberPOSITIVE_INFINITY, PromisePrototypeThen, ObjectPrototypeIsPrototypeOf, + SafeArrayIterator, SymbolFor, TypeError, } = window.__bootstrap.primordials; @@ -159,7 +160,11 @@ // 3. // TODO(@andreubotella): Error handling. if (typeof callback === "function") { - FunctionPrototypeCall(callback, globalThis, ...args); + FunctionPrototypeCall( + callback, + globalThis, + ...new SafeArrayIterator(args), + ); } else { // TODO(@andreubotella): eval doesn't seem to have a primordial, but // it can be redefined in the global scope. diff --git a/ext/url/00_url.js b/ext/url/00_url.js index 110890b7fa..b83cdd17d8 100644 --- a/ext/url/00_url.js +++ b/ext/url/00_url.js @@ -18,6 +18,7 @@ ArrayPrototypeSort, ArrayPrototypeSplice, ObjectKeys, + SafeArrayIterator, StringPrototypeSlice, Symbol, SymbolFor, @@ -345,7 +346,12 @@ "op_url_parse_search_params", StringPrototypeSlice(this.search, 1), ); - ArrayPrototypeSplice(params, 0, params.length, ...newParams); + ArrayPrototypeSplice( + params, + 0, + params.length, + ...new SafeArrayIterator(newParams), + ); } } diff --git a/ext/web/00_infra.js b/ext/web/00_infra.js index 40595be768..a250dd69b9 100644 --- a/ext/web/00_infra.js +++ b/ext/web/00_infra.js @@ -18,6 +18,7 @@ StringPrototypePadStart, TypeError, ArrayPrototypeJoin, + SafeArrayIterator, StringPrototypeCharAt, StringPrototypeMatch, StringPrototypeSlice, @@ -31,11 +32,21 @@ const ASCII_DIGIT = ["\u0030-\u0039"]; const ASCII_UPPER_ALPHA = ["\u0041-\u005A"]; const ASCII_LOWER_ALPHA = ["\u0061-\u007A"]; - const ASCII_ALPHA = [...ASCII_UPPER_ALPHA, ...ASCII_LOWER_ALPHA]; - const ASCII_ALPHANUMERIC = [...ASCII_DIGIT, ...ASCII_ALPHA]; + const ASCII_ALPHA = [ + ...new SafeArrayIterator(ASCII_UPPER_ALPHA), + ...new SafeArrayIterator(ASCII_LOWER_ALPHA), + ]; + const ASCII_ALPHANUMERIC = [ + ...new SafeArrayIterator(ASCII_DIGIT), + ...new SafeArrayIterator(ASCII_ALPHA), + ]; const HTTP_TAB_OR_SPACE = ["\u0009", "\u0020"]; - const HTTP_WHITESPACE = ["\u000A", "\u000D", ...HTTP_TAB_OR_SPACE]; + const HTTP_WHITESPACE = [ + "\u000A", + "\u000D", + ...new SafeArrayIterator(HTTP_TAB_OR_SPACE), + ]; const HTTP_TOKEN_CODE_POINT = [ "\u0021", @@ -53,7 +64,7 @@ "\u0060", "\u007C", "\u007E", - ...ASCII_ALPHANUMERIC, + ...new SafeArrayIterator(ASCII_ALPHANUMERIC), ]; const HTTP_TOKEN_CODE_POINT_RE = new RegExp( `^[${regexMatcher(HTTP_TOKEN_CODE_POINT)}]+$`, diff --git a/ext/web/02_event.js b/ext/web/02_event.js index b32bb01b85..e85b4f5cbc 100644 --- a/ext/web/02_event.js +++ b/ext/web/02_event.js @@ -31,6 +31,7 @@ ObjectGetOwnPropertyDescriptor, ObjectPrototypeIsPrototypeOf, ReflectDefineProperty, + SafeArrayIterator, Symbol, SymbolFor, SymbolToStringTag, @@ -1061,7 +1062,7 @@ object: this, evaluate: ObjectPrototypeIsPrototypeOf(ErrorEvent.prototype, this), keys: [ - ...EVENT_PROPS, + ...new SafeArrayIterator(EVENT_PROPS), "message", "filename", "lineno", @@ -1122,7 +1123,7 @@ object: this, evaluate: ObjectPrototypeIsPrototypeOf(CloseEvent.prototype, this), keys: [ - ...EVENT_PROPS, + ...new SafeArrayIterator(EVENT_PROPS), "wasClean", "code", "reason", @@ -1154,7 +1155,7 @@ object: this, evaluate: ObjectPrototypeIsPrototypeOf(MessageEvent.prototype, this), keys: [ - ...EVENT_PROPS, + ...new SafeArrayIterator(EVENT_PROPS), "data", "origin", "lastEventId", @@ -1187,7 +1188,7 @@ object: this, evaluate: ObjectPrototypeIsPrototypeOf(CustomEvent.prototype, this), keys: [ - ...EVENT_PROPS, + ...new SafeArrayIterator(EVENT_PROPS), "detail", ], })); @@ -1217,7 +1218,7 @@ object: this, evaluate: ObjectPrototypeIsPrototypeOf(ProgressEvent.prototype, this), keys: [ - ...EVENT_PROPS, + ...new SafeArrayIterator(EVENT_PROPS), "lengthComputable", "loaded", "total", diff --git a/ext/web/05_base64.js b/ext/web/05_base64.js index 7f4b607c9b..1244ecfd5c 100644 --- a/ext/web/05_base64.js +++ b/ext/web/05_base64.js @@ -19,6 +19,7 @@ ArrayPrototypeMap, StringPrototypeCharCodeAt, ArrayPrototypeJoin, + SafeArrayIterator, StringFromCharCode, TypedArrayFrom, Uint8Array, @@ -38,7 +39,7 @@ const uint8Array = forgivingBase64Decode(data); const result = ArrayPrototypeMap( - [...uint8Array], + [...new SafeArrayIterator(uint8Array)], (byte) => StringFromCharCode(byte), ); return ArrayPrototypeJoin(result, ""); @@ -55,16 +56,19 @@ prefix, context: "Argument 1", }); - const byteArray = ArrayPrototypeMap([...data], (char) => { - const charCode = StringPrototypeCharCodeAt(char, 0); - if (charCode > 0xff) { - throw new DOMException( - "The string to be encoded contains characters outside of the Latin1 range.", - "InvalidCharacterError", - ); - } - return charCode; - }); + const byteArray = ArrayPrototypeMap( + [...new SafeArrayIterator(data)], + (char) => { + const charCode = StringPrototypeCharCodeAt(char, 0); + if (charCode > 0xff) { + throw new DOMException( + "The string to be encoded contains characters outside of the Latin1 range.", + "InvalidCharacterError", + ); + } + return charCode; + }, + ); return forgivingBase64Encode(TypedArrayFrom(Uint8Array, byteArray)); } diff --git a/ext/web/10_filereader.js b/ext/web/10_filereader.js index 039d3395d4..c50635ea8c 100644 --- a/ext/web/10_filereader.js +++ b/ext/web/10_filereader.js @@ -30,6 +30,7 @@ ObjectDefineProperty, ObjectPrototypeIsPrototypeOf, queueMicrotask, + SafeArrayIterator, StringFromCodePoint, Symbol, TypedArrayPrototypeSet, @@ -484,7 +485,11 @@ if (typeof wrappedHandler.handler !== "function") { return; } - return FunctionPrototypeCall(wrappedHandler.handler, this, ...args); + return FunctionPrototypeCall( + wrappedHandler.handler, + this, + ...new SafeArrayIterator(args), + ); } wrappedHandler.handler = handler; return wrappedHandler; diff --git a/ext/webgpu/01_webgpu.js b/ext/webgpu/01_webgpu.js index 3531dd7972..be880d81df 100644 --- a/ext/webgpu/01_webgpu.js +++ b/ext/webgpu/01_webgpu.js @@ -32,6 +32,7 @@ PromisePrototypeThen, PromiseReject, PromiseResolve, + SafeArrayIterator, Set, SetPrototypeEntries, SetPrototypeForEach, @@ -543,7 +544,9 @@ } [SymbolFor("Deno.privateCustomInspect")](inspect) { - return `${this.constructor.name} ${inspect([...this.values()])}`; + return `${this.constructor.name} ${ + inspect([...new SafeArrayIterator(this.values())]) + }`; } } @@ -1923,7 +1926,7 @@ const { err } = core.opSync("op_webgpu_buffer_unmap", { bufferRid, mappedRid, - }, ...(write ? [new Uint8Array(buffer)] : [])); + }, ...new SafeArrayIterator(write ? [new Uint8Array(buffer)] : [])); device.pushError(err); if (err) return; } diff --git a/ext/websocket/02_websocketstream.js b/ext/websocket/02_websocketstream.js index 0f4cecaa5d..d41dcceef9 100644 --- a/ext/websocket/02_websocketstream.js +++ b/ext/websocket/02_websocketstream.js @@ -9,6 +9,8 @@ const { writableStreamClose, Deferred } = window.__bootstrap.streams; const { DOMException } = window.__bootstrap.domException; const { add, remove } = window.__bootstrap.abortSignal; + const { headersFromHeaderList, headerListFromHeaders, fillHeaders } = + window.__bootstrap.headers; const { ArrayPrototypeJoin, @@ -121,6 +123,11 @@ ); } + const headers = headersFromHeaderList([], "request"); + if (options.headers !== undefined) { + fillHeaders(headers, options.headers); + } + const cancelRid = core.opSync( "op_ws_check_permission_and_cancel_handle", this[_url], @@ -144,7 +151,7 @@ ? ArrayPrototypeJoin(options.protocols, ", ") : "", cancelHandle: cancelRid, - headers: [...new Headers(options.headers).entries()], + headers: headerListFromHeaders(headers), }), (create) => { options.signal?.[remove](abort); diff --git a/ext/webstorage/01_webstorage.js b/ext/webstorage/01_webstorage.js index 7ed7b6618a..831f63f591 100644 --- a/ext/webstorage/01_webstorage.js +++ b/ext/webstorage/01_webstorage.js @@ -6,6 +6,7 @@ const core = window.Deno.core; const webidl = window.__bootstrap.webidl; const { + SafeArrayIterator, Symbol, SymbolFor, ObjectDefineProperty, @@ -116,7 +117,7 @@ get(target, key) { if (typeof key == "symbol") return target[key]; if (key in target) { - return ReflectGet(...arguments); + return ReflectGet(...new SafeArrayIterator(arguments)); } else { return target.getItem(key) ?? undefined; } diff --git a/runtime/js/06_util.js b/runtime/js/06_util.js index e934c4f0e9..c643f758a0 100644 --- a/runtime/js/06_util.js +++ b/runtime/js/06_util.js @@ -7,6 +7,7 @@ Error, ObjectPrototypeIsPrototypeOf, Promise, + SafeArrayIterator, StringPrototypeReplace, TypeError, } = window.__bootstrap.primordials; @@ -26,7 +27,10 @@ if (logDebug) { // if we destructure `console` off `globalThis` too early, we don't bind to // the right console, therefore we don't log anything out. - globalThis.console.log(`DEBUG ${logSource} -`, ...args); + globalThis.console.log( + `DEBUG ${logSource} -`, + ...new SafeArrayIterator(args), + ); } } diff --git a/runtime/js/40_testing.js b/runtime/js/40_testing.js index 62eb1e9a98..5ff5c6e151 100644 --- a/runtime/js/40_testing.js +++ b/runtime/js/40_testing.js @@ -24,6 +24,7 @@ RegExp, RegExpPrototypeTest, Set, + SafeArrayIterator, StringPrototypeEndsWith, StringPrototypeIncludes, StringPrototypeSlice, @@ -278,7 +279,10 @@ finishing test case.`; const post = core.resources(); - const allResources = new Set([...ObjectKeys(pre), ...ObjectKeys(post)]); + const allResources = new Set([ + ...new SafeArrayIterator(ObjectKeys(pre)), + ...new SafeArrayIterator(ObjectKeys(post)), + ]); const details = []; for (const resource of allResources) { @@ -322,7 +326,7 @@ finishing test case.`; }); try { - await fn(...params); + await fn(...new SafeArrayIterator(params)); } catch (err) { throw err; } finally { @@ -423,7 +427,7 @@ finishing test case.`; const token = pledgePermissions(permissions); try { - await fn(...params); + await fn(...new SafeArrayIterator(params)); } finally { restorePermissions(token); }