Skip to content

Commit ad7c306

Browse files
committed
fix validation of iterators .next() results an objects in Iterator.{ zip, zipKeyed } polyfills
1 parent 396ecf7 commit ad7c306

File tree

4 files changed

+26
-2
lines changed

4 files changed

+26
-2
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
- Fixed order of arguments validation in `Array.prototype.flat` polyfill
1919
- Fixed handling strings as iterables in `Iterator.{ zip, zipKeyed }` polyfills
2020
- Fixed some cases of iterators closing in `Iterator.{ zip, zipKeyed }` polyfills
21+
- Fixed validation of iterators `.next()` results an objects in `Iterator.{ zip, zipKeyed }` polyfills
2122
- Fixed a lack of early error in `Iterator.concat` polyfill on primitive as an iterator
2223
- Fixed iterator closing in `Set.prototype.{ isDisjointFrom, isSupersetOf }` polyfill
2324
- Fixed (updated following the final spec) one more case `Set.prototype.difference` polyfill with updating `this`

packages/core-js/internals/iterator-zip.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
'use strict';
22
var call = require('../internals/function-call');
33
var uncurryThis = require('../internals/function-uncurry-this');
4+
var anObject = require('../internals/an-object');
45
var createIteratorProxy = require('../internals/iterator-create-proxy');
56
var iteratorCloseAll = require('../internals/iterator-close-all');
67

@@ -31,7 +32,7 @@ var IteratorProxy = createIteratorProxy(function () {
3132
result = padding[i];
3233
} else {
3334
try {
34-
result = call(iter.next, iter.iterator);
35+
result = anObject(call(iter.next, iter.iterator));
3536
done = result.done;
3637
result = result.value;
3738
} catch (error) {
@@ -54,7 +55,7 @@ var IteratorProxy = createIteratorProxy(function () {
5455
for (var k = 1; k < iterCount; k++) {
5556
// eslint-disable-next-line max-depth -- specification case
5657
try {
57-
open = call(iters[k].next, iters[k].iterator);
58+
open = anObject(call(iters[k].next, iters[k].iterator));
5859
openDone = open.done;
5960
open = open.value;
6061
} catch (error) {

tests/unit-global/esnext.iterator.zip.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,4 +157,15 @@ QUnit.test('Iterator.zip', assert => {
157157

158158
assert.throws(() => zip(['hello', [1, 2, 3]]), TypeError, 'rejects string iterables');
159159
assert.throws(() => zip([42, [1, 2, 3]]), TypeError, 'rejects number iterables');
160+
{
161+
// iterator-zip: .next() result must be validated as an object
162+
const primitiveNextIter = {
163+
[Symbol.iterator]() {
164+
return { next() { return 42; } };
165+
},
166+
};
167+
const normalIter = [1, 2, 3];
168+
const zipped = zip([primitiveNextIter, normalIter]);
169+
assert.throws(() => zipped.next(), TypeError, 'throws on non-object .next() result');
170+
}
160171
});

tests/unit-pure/esnext.iterator.zip.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,4 +157,15 @@ QUnit.test('Iterator.zip', assert => {
157157

158158
assert.throws(() => zip(['hello', [1, 2, 3]]), TypeError, 'rejects string iterables');
159159
assert.throws(() => zip([42, [1, 2, 3]]), TypeError, 'rejects number iterables');
160+
{
161+
// iterator-zip: .next() result must be validated as an object
162+
const primitiveNextIter = {
163+
[Symbol.iterator]() {
164+
return { next() { return 42; } };
165+
},
166+
};
167+
const normalIter = [1, 2, 3];
168+
const zipped = zip([primitiveNextIter, normalIter]);
169+
assert.throws(() => zipped.next(), TypeError, 'throws on non-object .next() result');
170+
}
160171
});

0 commit comments

Comments
 (0)