diff options
author | janekptacijarabaci <janekptacijarabaci@seznam.cz> | 2018-03-15 21:12:03 +0100 |
---|---|---|
committer | janekptacijarabaci <janekptacijarabaci@seznam.cz> | 2018-03-15 21:12:03 +0100 |
commit | 25550ce903d01f31bead59de945e4adf86819440 (patch) | |
tree | 25fbd8c0ef297a8252d67a1dde50e94db1abd8ec /js/src/builtin | |
parent | 75c9377766326589faa844a95d5997a156f6aed0 (diff) | |
download | UXP-25550ce903d01f31bead59de945e4adf86819440.tar UXP-25550ce903d01f31bead59de945e4adf86819440.tar.gz UXP-25550ce903d01f31bead59de945e4adf86819440.tar.lz UXP-25550ce903d01f31bead59de945e4adf86819440.tar.xz UXP-25550ce903d01f31bead59de945e4adf86819440.zip |
Close iterator after error in Array.from
Issue #17
Diffstat (limited to 'js/src/builtin')
-rw-r--r-- | js/src/builtin/Array.js | 46 |
1 files changed, 32 insertions, 14 deletions
diff --git a/js/src/builtin/Array.js b/js/src/builtin/Array.js index 54b47b72f..5ab0b71be 100644 --- a/js/src/builtin/Array.js +++ b/js/src/builtin/Array.js @@ -784,7 +784,7 @@ function ArrayKeys() { return CreateArrayIterator(this, ITEM_KIND_KEY); } -// ES6 draft rev31 (2015/01/15) 22.1.2.1 Array.from(source[, mapfn[, thisArg]]). +// ES 2017 draft 0f10dba4ad18de92d47d421f378233a2eae8f077 22.1.2.1 function ArrayFrom(items, mapfn=undefined, thisArg=undefined) { // Step 1. var C = this; @@ -795,43 +795,61 @@ function ArrayFrom(items, mapfn=undefined, thisArg=undefined) { ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(1, mapfn)); var T = thisArg; - // Steps 4-5. + // Step 4. var usingIterator = GetMethod(items, std_iterator); - // Step 6. + // Step 5. if (usingIterator !== undefined) { - // Steps 6.a-c. + // Steps 5.a-c. var A = IsConstructor(C) ? new C() : []; - // Steps 6.d-e. + // Step 5.c. var iterator = GetIterator(items, usingIterator); - // Step 6.f. + // Step 5.d. var k = 0; - // Step 6.g. + // Step 5.e. // These steps cannot be implemented using a for-of loop. // See <https://bugs.ecmascript.org/show_bug.cgi?id=2883>. while (true) { - // Steps 6.g.i-iii. + // Step 5.e.i. + // Disabled for performance reason. We won't hit this case on + // normal array, since _DefineDataProperty will throw before it. + // We could hit this when |A| is a proxy and it ignores + // |_DefineDataProperty|, but it happens only after too long loop. + /* + if (k >= 0x1fffffffffffff) { + IteratorCloseThrow(iterator); + ThrowTypeError(JSMSG_TOO_LONG_ARRAY); + } + */ + + // Step 5.e.iii. var next = callContentFunction(iterator.next, iterator); if (!IsObject(next)) ThrowTypeError(JSMSG_NEXT_RETURNED_PRIMITIVE); - // Step 6.g.iv. + // Step 5.e.iv. if (next.done) { A.length = k; return A; } - // Steps 6.g.v-vi. + // Steps 5.e.v. var nextValue = next.value; - // Steps 6.g.vii-viii. - var mappedValue = mapping ? callContentFunction(mapfn, thisArg, nextValue, k) : nextValue; + // Steps 5.e.vi-vii. + try { + var mappedValue = mapping ? callContentFunction(mapfn, thisArg, nextValue, k) : nextValue; - // Steps 6.g.ix-xi. - _DefineDataProperty(A, k++, mappedValue); + // Steps 5.e.ii (reordered), 5.e.viii. + _DefineDataProperty(A, k++, mappedValue); + } catch (e) { + // Steps 5.e.vi.2, 5.e.ix. + IteratorCloseThrow(iterator); + throw e; + } } } |